程式範例
[Day-3]從電商網站學身分驗證- 上 @CodeSandbox
今日學習關鍵字
firebase / bootstrap / React-Toastify
繼上篇已經把連結都設定好了,再來就要打造頁面內容!
如果要實作登入登出,總要先有帳號,而要有帳號認證,就要有對應的後端驗證平台,也就是今天的主角 Firebase 拉。
今日順序
註冊功能
- 設定 Firebase 並連到專案
- 完成註冊表單
- 完成點擊註冊送確認信到信箱
- 顯示完成通知
- 完成點擊確認信後畫面
那就馬上開始吧!
第一部分:註冊功能
第一步:註冊 Firebase
首先要去註冊前我們先去申請 Firebase,簡單來說,Firebase 是一個雲端的後端平台(延伸閱讀:Firebase 是什麼 ? 集 APP 後端開發與分析於一身的強大工具!)
首先註冊完畢點擊 console
並且新增一個新的專案
點擊 Web 選項
就可以看到 Firebase 的 SDK,把這個複製回我們的專案就可以連上 Firebase 拉
回到專案資料夾,在 src
底下開啟一個 firebase.js
的檔案,並且把剛剛那串 SDK 輸入進去,並且下載 firebase
npm install firebase
至於如何導入 Firebase,可以參考這個相關文件
firebase.js
import firebase from "firebase/app";
import "firebase/auth";
var firebaseConfig = {
apiKey: "AIzaSyDOCAbC123dEf456GhI789jKl01-MnO",
authDomain: "myapp-project-123.firebaseapp.com",
databaseURL: "https://myapp-project-123.firebaseio.com",
projectId: "myapp-project-123",
storageBucket: "myapp-project-123.appspot.com",
messagingSenderId: "65211879809",
appId: "1:65211879909:web:3ae38ef1cdcb2e01fe5f0c",
measurementId: "G-8GSGZQ44ST"
};
firebase.initializeApp(firebaseConfig);
export const auth = firebase.auth();
第二步: 打造註冊表單
這裡主要可以學習的點是 Bootstrap,橫向主要被切成十二塊,於是
col-4
就是十二塊內的四塊,而 offset-4
則是跳過四塊。所以如果要內容物置中的話就是 col-4 offset-4
,再搭配尺寸sm
、md
等等,就會看到底下的 col-md-6 offset-md-3
這樣的用法。
首先記得要在 public/index.html
裡面引入 bootstrap
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
再來回到我們的 src/Register.js
Register.js
const Register = () => (
<form onSubmit={handleSubmit}>
...
return (
<div className="container p-5">
<div className="row">
<div className="col-md-6 offset-md-3">
<h4>Register</h4>
</div>
</div>
</div>
);
};
export default Register;
第三步: 當註冊表單點擊時發送 Email
主要就是點擊 handleSubmit 的這個 function 要做事情,而 Firebase 就有內建發送 email 的 API
,有些名詞解釋來源如下
handleCodeInApp
register.form
const handleSubmit = async (e) => {
e.preventDefault(); // 避免送出表單
const config = {
//Email 裡面的信件連結
url: http://localhost:8000/registercomplete,
//設定 Mail 被網頁或 Android 開啟,預設是 false 意指無論透過網頁或 android 都是網頁優先,設定 true 則是看使用者用什麼裝置點擊就用什麼裝置打開
handleCodeInApp: true
};
await auth.sendSignInLinkToEmail(email, config);
// 將 email 存入 localstorage,待會用戶點確認信回到網頁的時候可以直接填入 mail 帳號
window.localStorage.setItem("emailForRegistration", email);
setEmail("");
};
第四步: 註冊成功時在頁面上顯現成功通知
這裡我們所使用的工具是 React-Toastify
,這可以在畫面右上角顯示例如登入成功的訊息,首先也是先安裝
npm install react-toastify
得用引入三個參數
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css"
import { toast } from "react-toastify";
通常前兩個建議放在上層物件,如 Router 的地方,範例如下
App.js
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css"
const App = () => {
return (
<>
<Header />
<ToastContainer />
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/login" component={Login} />
<Route exact path="/register" component={Register} />
</Switch>
</>
);
};
而在需要顯示訊息的頁面再引入 toast,假如是成功訊息則使用toast.success('成功訊息')
;失敗的話則是 toast.error('失敗訊息')
範例如下
Register.js
const handleSubmit = async (e) => {
const config = {
url: process.env.REACT_APP_REGISTER_REDIRECT_URL,
handleCodeInApp: tru e
};
await auth.sendSignInLinkToEmail(email, config);
toast.success(
`Email is sent to ${email}. Click the link to complete your registration.`
);
...
};
第五步:用戶確認信導回完成註冊
我們再開一個 RegisterComplete.js
的頁面來處理,而頁面本身不難,這裡比較重要的是用戶輸入密碼準備註冊,點下按鈕的時候如何儲存帳號密碼
RegisterComplete.js
,這裡 firebse 也有一個現成的 API signInWithEmailLink
,傳入 email 跟信件內的網址即可,而信件內的網址我們使用 window.location.href
去取得
RegisterComplete.js
const handleSubmit = async (e) => {
try {
const result = await auth.signInWithEmailLink(
email,
window.location.href
);
} catch (error) {
console.log(error);
toast.error(error.message);
}
};
取得成功之後,透過 result.user.emailVerified
去確定 email 是否正確。
RegisterComplete.js
const handleSubmit = async (e) => {
try {
const result = await auth.signInWithEmailLink(
email,
window.location.href
);
if (result.user.emailVerified) {
window.localStorage.removeItem("emailForRegistration");
let user = auth.currentUser;
await user.updatePassword(password);
const idTokenResult = await user.getIdTokenResult();
//下次再做,將 user 資料存入 redux
// redirect
navigate('/')
}
} catch (error) {
console.log(error);
toast.error(error.message);
}
};
目前到這裡,註冊的流程算是大功告成!再來就是把從 firebase 拿到的 token 存入 redux 中,這樣之後任何有關要求登入的功能都可以從 redux 裡面拿到 token 的資料去認證拉!
程式範例
[Day-3]從電商網站學用戶註冊 @CodeSandbox