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

服务端集成Firebase Authentication实现路由鉴权的方法咨询

问题说明

你当前用的纯前端sessionStorage鉴权方案完全没有安全性:用户可以直接通过浏览器开发者工具篡改sessionStorage里的用户字段,也可以直接禁用页面JavaScript绕过校验,直接获取seller.html的全部内容,不存在任何防护能力。
你已经在项目里引入了firebase-admin服务端SDK,完全可以直接在服务端完成鉴权逻辑,不需要依赖客户端SDK实现路由保护。


具体实现方案

前置依赖安装

先安装cookie解析依赖,用来读取请求携带的cookie:

npm i cookie-parser

第一步:修改服务端基础配置

在server.js中引入cookie-parser并注册中间件:

const cookieParser = require('cookie-parser');
// 放在express.json()后面即可
app.use(cookieParser());

第二步:编写通用鉴权中间件

这个中间件会在所有受保护路由加载前执行,校验用户登录状态和权限:

async function requireAuth(req, res, next) {
  // 从cookie里取Firebase的身份凭证
  const idToken = req.cookies.firebaseToken;
  if (!idToken) return res.redirect('/login');

  try {
    // 用admin SDK验证token合法性,伪造、过期的token会直接抛出异常
    const decodedToken = await admin.auth().verifyIdToken(idToken);
    // 校验用户是否具备seller权限,这里的自定义claims由服务端控制,用户无法篡改
    if (decodedToken.seller !== true) return res.status(403).send('您没有访问该页面的权限');
    // 将解析后的用户信息挂载到req对象上,后续路由可直接使用
    req.user = decodedToken;
    next();
  } catch (error) {
    // token无效时清除残留cookie,跳转登录页
    res.clearCookie('firebaseToken');
    return res.redirect('/login');
  }
}

第三步:添加登录/登出接口

客户端登录成功拿到Firebase ID Token后,调用该接口把凭证存到安全Cookie中:

// 登录接口,接收客户端传来的ID Token
app.post('/api/auth/login', async (req, res) => {
  const { idToken } = req.body;
  try {
    // 先校验token合法性
    await admin.auth().verifyIdToken(idToken);
    // 设置HttpOnly Cookie,前端JavaScript无法读取,避免XSS攻击窃取凭证
    res.cookie('firebaseToken', idToken, {
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production', // 生产环境部署在HTTPS上时开启
      maxAge: 3600 * 1000, // 有效期和Firebase ID Token默认时长一致,为1小时
      sameSite: 'strict'
    });
    res.json({ code: 0, msg: '登录成功' });
  } catch (error) {
    res.status(401).json({ code: -1, msg: '登录凭证无效' });
  }
});

// 登出接口
app.post('/api/auth/logout', (req, res) => {
  res.clearCookie('firebaseToken');
  res.redirect('/login');
});

第四步:改造客户端登录逻辑

客户端用Firebase Auth完成邮箱密码登录后,不要只把用户信息存在sessionStorage,要拿到ID Token发给刚才写的登录接口:

// 客户端登录成功回调逻辑示例
const userCredential = await signInWithEmailAndPassword(auth, email, password);
const idToken = await userCredential.user.getIdToken();
// 把token发给服务端设置安全Cookie
await fetch('/api/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ idToken })
});
// 登录完成后跳转到卖家后台
window.location.href = '/seller';

第五步:给受保护路由挂载鉴权中间件

修改原来的/seller路由,加入requireAuth中间件:

app.get('/seller', requireAuth, (req, res) => {
  res.sendFile(path.join(staticPath, "seller.html"));
})

关键注意事项
  • 所有前端层面的权限校验都只能做体验优化,真正的权限判定必须在服务端完成。只要服务端没做校验,静态文件就可以被任意用户直接访问。
  • 用户的seller权限不要在前端设置,要通过firebase-admin在服务端调用admin.auth().setCustomUserClaims(uid, { seller: true })给对应用户添加自定义声明,这个声明会被包含在ID Token中,由Firebase服务端签名,用户无法篡改。
  • 你项目根目录下的1234.json是Firebase服务端凭证,拥有项目的最高操作权限,绝对不能泄露,不要传到公开代码仓库,也不要打包到前端静态资源里。
  • Firebase ID Token默认有效期1小时,可以在客户端加定时刷新逻辑,提前获取新的ID Token更新服务端Cookie,避免用户使用过程中因token过期被强制踢下线。

内容的提问来源于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 10:48:14