當我們拿到 Firebase 的 idToken 後,下一個問題就是 ——「要放哪裡?」
前端有三個常見選擇:
| 儲存方式 | 優點 | 缺點 | 適用情境 | 
|---|---|---|---|
| LocalStorage | 寫法簡單、刷新不會消失 | 暴露在 JS 環境,容易被 XSS 盜走 | 練習、後台系統、開發階段 | 
| Cookie(HttpOnly) | 可防止 JS 存取,安全性高 | 須後端設定、需配合 SameSite & Secure | 正式環境、敏感資料 | 
| Memory(React State / Context) | 不落地、不怕 XSS | 一刷新就消失,需要 Refresh Token | SPA + 自動刷新 Token | 
我們這邊會先用最容易上手的方式 👉 LocalStorage 實作
後面再告訴你為什麼正式環境建議改用 Cookie。
export const saveToken = (token) => {
  localStorage.setItem("idToken", token);
};
export const getToken = () => {
  return localStorage.getItem("idToken");
};
export const removeToken = () => {
  localStorage.removeItem("idToken");
};
放進登入流程(只示範概念)
import { saveToken } from "./utils/tokenStorage";
import { getAuth, signInWithEmailAndPassword } from "firebase/auth";
export const login = async (email, password) => {
  const auth = getAuth();
  const result = await signInWithEmailAndPassword(auth, email, password);
  const token = await result.user.getIdToken();
  saveToken(token);
  return result.user;
};
丟到 /auth/verify 時從 localStorage 撈
export const verifyWithStoredToken = async () => {
  const token = getToken();
  if (!token) throw new Error("沒有 Token");
  const res = await fetch("/auth/verify", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ idToken: token }),
  });
  if (!res.ok) {
    removeToken(); // 避免無效 Token 留著
    throw new Error("驗證失敗");
  }
  return res.json();
};
所以在「開發階段」可以用、但上線務必要換方式。