如何用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
相关产品推荐
相关产品推荐

