前面幾課你選好了資料庫、畫好了 schema,連 users 這張表都準備好了。但有個問題還沒解決:這張表裡的「人」是怎麼進來的?使用者要怎麼證明「我就是我」,而不是隨便一個人冒充?這就是 Authentication(身分驗證),也是讓 App 從玩具變成產品的第一道門。
登入這件事,本質上只是 App 在問一個問題:「你真的是你說的那個人嗎?」
Authentication 就是「確認你是誰」的過程。你打開 YouTube、Spotify、Notion,看到的那顆「Continue with Google」按鈕,做的就是這件事:在你動任何資料之前,先確認你的身分。
它常跟另一個詞搞混:Authorization(授權),那是「你能做什麼」。先有 Authentication(你是小明),才談得上 Authorization(小明只能改自己的訂單)。這一課先把「你是誰」講清楚,「你能做什麼」留到 6-6 的保護路由。
很多人想到登入,第一反應是「做一個帳號密碼欄位」。我們手動走一次,看看為什麼這條路很危險,以及為什麼把它交出去才是對的決定。
| password 欄存的東西 | |
|---|---|
| ming@x.com | hunter2 |
| hua@x.com | hunter2 |
users 表有一個 password 欄,裡面存著看得懂的字串。最該做的是什麼?按「下一步」自己走一遍,看看按下按鈕之後,瀏覽器到底跑去哪、誰在跟誰講話。
你進夜店不會把家裡鑰匙交給門口的人,你出示護照,他確認章是真的就放你進去。OAuth 就是這個機制:你的 App 不碰使用者的 Google 密碼,只拿到一張「Google 幫忙蓋章的證明」。所以叫「用 Google 登入」既安全又省事。
一切從這顆按鈕開始。你的 App 不會自己問密碼,而是把使用者交給 Google。
精準來說,Google 導回來的不是直接可用的 token,而是一段「authorization code」。要再用這段碼跟 Google 換真正的 token,這一步叫 token exchange,而且發生在後端,因為要用到只有後端才有的密鑰,前端永遠拿不到。
為了防止有人中途攔截這段碼,現代流程還會加上 PKCE 和 state 兩道防偽(防 CSRF)。好消息是:用 Firebase 的話,這些它都幫你處理好了,你不用自己實作。知道有這層就好。
前面那趟流程要能跑,前提是先在 Firebase Console 把 Google 這個登入方式開起來。我們模擬一遍實際要點哪裡。
signInWithPopup,卻忘了提「登入方式要先在 Firebase Console 開」「Callback URL 要兩邊登記」。結果你一按就壞,還以為是 code 寫錯。難的都在前面那段設定。真正寫的程式碼只有一個 function 呼叫,按下按鈕就會啟動剛才那趟登入旅程。
const provider = new GoogleAuthProvider(); await signInWithPopup(auth, provider);
就這樣兩行。GoogleAuthProvider 指定用 Google 登入,signInWithPopup 跳出那個熟悉的選帳號視窗。其餘整趟跳轉、換 token、建 session,Firebase 全包了。
登入成功只是開始。App 怎麼「一直記得你」?出問題時又該往哪看?
登入成功後,Firebase 在瀏覽器存了兩樣東西:一張 ID token(短效,證明「你現在是登入狀態」)和一張 refresh token(長效,用來在前者過期時換新的)。每次你對後端發請求,就帶著 ID token,後端看一眼就知道是誰。
| Name | Value | Domain | Path | Expires | Size | HttpOnly | Secure | SameSite |
|---|---|---|---|---|---|---|---|---|
| firebaseIdToken | eyJhbGci….SflKx | your-app.com | / | 2024-05-29 18:00 | 412 | ✓ | ✓ | Lax |
| firebaseRefreshToken | v1.Mr8… | your-app.com | / | 2024-08-27 18:00 | 88 | ✓ | ✓ | Lax |
Error 400: redirect_uri_mismatch最可能的原因是?Error: Unsupported provider: provider is not enabled最可能的原因是?登入後沒有報錯,但 session 一直是 null最可能的原因是?現在 App 認得你是誰了。但「登入的人才能看 /dashboard」這件事要怎麼擋?未登入的人闖進來又該怎麼導回登入頁?下一段我們用 Middleware 當網站保全,把「你能做什麼」這條界線畫出來。