示例说明
Firebase ID 令牌默认一小时过期,前端如果缓存旧令牌会在一小时后集体 401。正确做法是把取令牌的动作放进请求发生时:getIdToken 会在令牌仍有效时返回缓存值,过期或强制刷新时自动用刷新令牌换新。onAuthStateChanged 则是登录态唯一可信来源,登录登出都能即时感知。
技术要点
- getIdToken 每次请求时获取而非启动缓存
- 强制刷新参数应对权限变更场景
- onAuthStateChanged 是会话状态单一事实源
代码解读
初始化后注册状态监听输出用户与匿名标记;authorizedFetch 先检查 currentUser 存在,再取令牌拼进授权头发起请求,上游 401 时抛出明确错误供上层重新走登录流程。signInAnonymously 演示无注册流程的临时身份建立。
使用建议
匿名身份要迁移成正式账号时用 link 系列 API。安全规则应以令牌声明为依据在服务端执行,不要信任前端代码路径。刷新失败通常意味着刷新令牌被吊销,应清理本地态引导重登。
代码示例
import { initializeApp } from 'firebase/app';
import {
getAuth, onAuthStateChanged, signInAnonymously,
} from 'firebase/auth';
const app = initializeApp({
apiKey: process.env.FIREBASE_API_KEY,
authDomain: 'demo.firebaseapp.com',
projectId: 'demo-project',
});
const auth = getAuth(app);
onAuthStateChanged(auth, (user) => {
if (user) {
console.log('signed in as', user.uid, 'anonymous:', user.isAnonymous);
} else {
console.log('signed out');
}
});
await signInAnonymously(auth);
async function authorizedFetch(path) {
const user = auth.currentUser;
if (!user) throw new Error('auth required');
// getToken 强制刷新已过期的 ID 令牌,保持短期凭证语义
const token = await user.getIdToken(true);
const res = await fetch('https://api.example.com' + path, {
headers: { Authorization: 'Bearer ' + token },
});
if (res.status === 401) throw new Error('token rejected upstream');
return res.json();
}
const profile = await authorizedFetch('/me');
console.log('profile loaded:', Object.keys(profile).length, 'fields');