← 中文资源

简体中文版本

Firebase Auth 会话令牌刷新

监听 Firebase 认证状态变化,每次调用前获取最新 ID 令牌并强制刷新过期凭证,把短时效令牌语义交给 SDK 透明维护。

阅读英文原文

示例说明

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');