為什麼需要重新驗證?
在 Firebase 裡,若使用者登入時間太久、或嘗試進行敏感操作(Sensitive Operation),
像是:
Firebase 都會要求「重新驗證」,
確保是本人操作,而不是被盜用的登入狀態。
reauthenticateWithCredential()Firebase 提供的重新驗證函式:
import { EmailAuthProvider, reauthenticateWithCredential } from "firebase/auth";
我們會先要求使用者輸入「當前密碼」,
然後用這個密碼重新建立一個 credential 驗證。
import {
  getAuth,
  updatePassword,
  EmailAuthProvider,
  reauthenticateWithCredential,
} from "firebase/auth";
export const secureUpdatePassword = async (currentPassword, newPassword) => {
  const auth = getAuth();
  const user = auth.currentUser;
  if (!user) throw new Error("尚未登入");
  try {
    // 建立憑證(用舊密碼重新驗證身份)
    const credential = EmailAuthProvider.credential(user.email, currentPassword);
    // 重新驗證
    await reauthenticateWithCredential(user, credential);
    console.log("使用者重新驗證成功");
    // 修改密碼
    await updatePassword(user, newPassword);
    console.log("密碼已更新成功");
  } catch (error) {
    console.error("密碼更新失敗:", error.message);
    throw error;
  }
};
這是一個安全版「變更密碼」頁面(需要輸入舊密碼)
import React, { useState } from "react";
import { secureUpdatePassword } from "../firebase/authService";
export default function ChangePasswordSecure() {
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(false);
  const handleChange = async (e) => {
    e.preventDefault();
    setLoading(true);
    setMessage("");
    try {
      await secureUpdatePassword(currentPassword, newPassword);
      setMessage("✅ 密碼修改成功,請重新登入。");
    } catch (err) {
      setMessage(`❌ 錯誤:${err.message}`);
    } finally {
      setLoading(false);
    }
  };
  return (
    <div className="p-4 max-w-md mx-auto">
      <h2 className="text-xl font-bold mb-2">安全變更密碼</h2>
      <form onSubmit={handleChange} className="space-y-3">
        <input
          type="password"
          value={currentPassword}
          onChange={(e) => setCurrentPassword(e.target.value)}
          placeholder="目前密碼"
          className="w-full p-2 border rounded"
          required
        />
        <input
          type="password"
          value={newPassword}
          onChange={(e) => setNewPassword(e.target.value)}
          placeholder="新密碼"
          className="w-full p-2 border rounded"
          required
        />
        <button
          type="submit"
          disabled={loading}
          className="w-full bg-blue-500 text-white py-2 rounded"
        >
          {loading ? "更新中..." : "更新密碼"}
        </button>
      </form>
      {message && <p className="mt-3 text-sm text-gray-600">{message}</p>}
    </div>
  );
}
import { signOut } from "firebase/auth";
await signOut(auth);
dispatch(logout());