You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Firebase Custom Claims实现特定角色路由重定向

Express 结合 Firebase Custom Claims 实现路由权限拦截方案

你不需要单独写/getMyClaims接口反复拉取用户信息,Firebase ID令牌本身就携带了签发时的所有Custom Claims,直接在Express中间件层校验令牌即可完成权限拦截,实现步骤如下:

1. 编写两层鉴权中间件

第一层校验用户登录状态、解码令牌拿到Claims,第二层校验用户角色,不满足直接重定向:

// 替换成你自己的firebase admin初始化文件路径
const admin = require('./firebase-admin-init');

// 登录态校验中间件
const authGuard = async (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (!authHeader?.startsWith('Bearer ')) return res.sendStatus(401);
  const token = authHeader.split(' ')[1];
  try {
    // verifyIdToken会自动校验令牌合法性、过期时间,直接解码出所有claims
    const decodedUser = await admin.auth().verifyIdToken(token);
    req.user = decodedUser;
    next();
  } catch (e) {
    return res.sendStatus(401);
  }
};

// 卖家权限校验中间件
const sellerGuard = (req, res, next) => {
  // 解码后的用户信息里直接带了你之前设置的type字段
  if (req.user.type === 'customer') return res.redirect('/');
  next();
};

module.exports = { authGuard, sellerGuard };

2. 客户端请求时携带合法令牌

你之前已经在客户端能拿到ID令牌,所有请求受保护路由时把令牌放到请求头即可,不需要额外请求Claims接口:

// 客户端访问/seller路由的示例逻辑
async function loadSellerPage() {
  const currentUser = firebase.auth().currentUser;
  if (!currentUser) return window.location.replace('/login');
  // 传true强制刷新令牌,避免刚设置完claims旧令牌没更新的问题
  const tokenRes = await currentUser.getIdTokenResult(true);
  const resp = await fetch('/seller', {
    headers: {
      Authorization: `Bearer ${tokenRes.token}`
    }
  });
  // 后端返回302重定向时自动跳转
  if (resp.redirected) window.location.replace(resp.url);
  // 正常拿到页面内容就渲染
  document.body.innerHTML = await resp.text();
}

3. 给/seller路由挂载中间件

按顺序挂载两个中间件,先校验登录再校验角色,通过后才会执行真正的路由逻辑:

const express = require('express');
const { authGuard, sellerGuard } = require('./auth-middleware');
const app = express();

app.get('/seller', authGuard, sellerGuard, (req, res) => {
  // 走到这里的用户都是非customer角色,正常返回卖家页面即可
  res.sendFile(__dirname + '/public/seller.html');
});

app.listen(3000);

补充说明:不要在每次请求时调用admin.auth().getUser()拉取用户信息拿Claims,ID令牌解码后的内容已经包含所有签发时的Custom Claims,直接用解码结果做校验性能更高,也符合JWT的无状态校验逻辑。如果刚给用户更新完角色,客户端调用getIdToken(true)强制刷新一次令牌就能拿到最新权限,不用等令牌自动过期。

内容的提问来源于stack exchange,提问作者Mergo22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:33:29