Firebase 8.2.3中auth.currentUser跨会话覆盖问题求助
问题根源
你遇到的串号问题,核心原因是后端全局共享的Firebase Auth实例导致状态污染:
- 你导出的
auth是全局单例对象,auth.currentUser属于这个全局实例的状态 - 当不同用户的请求到达后端时,都会读取这个全局的
currentUser,后登录的用户会覆盖之前的状态,最终所有请求都拿到最后登录的用户信息
解决方案
在Node.js后端处理Firebase Auth,不能直接依赖全局的auth.currentUser,必须通过会话(Session)+ ID Token实现用户请求的状态隔离,步骤如下:
1. 登录成功后存储用户ID Token到会话
修改登录代码,在用户登录成功后获取ID Token并存入会话(这里假设你用express-session做会话管理):
auth.signInWithEmailAndPassword(email, password) .then(async (userCredential) => { // 获取当前用户的ID Token const idToken = await userCredential.user.getIdToken(); // 将Token存入会话 req.session.idToken = idToken; res.redirect('/'); }) .catch((error) => { var errorMessage = error.message; return res.render('login', { error: errorMessage, state: state }); });
2. 用中间件验证会话中的Token,获取当前用户
创建一个身份验证中间件,每次请求时验证会话里的Token,确保每个请求拿到的是对应用户的信息:
// 身份验证中间件 async function authenticateUser(req, res, next) { // 会话中没有Token,说明未登录 if (!req.session.idToken) { return res.redirect('/login'); } try { // 验证ID Token的有效性 const decodedToken = await auth.verifyIdToken(req.session.idToken); // 将用户信息挂载到req对象,后续路由可直接使用 req.user = decodedToken; next(); } catch (error) { // Token无效/过期,清除会话并跳转登录 req.session.destroy(); res.redirect('/login'); } } // 在需要验证用户身份的路由上使用中间件 app.get('/', authenticateUser, (req, res) => { // 这里通过req.user获取当前登录用户的信息,而非auth.currentUser res.render('home', { user: req.user }); });
3. 退出登录时清除会话
app.get('/logout', (req, res) => { // 销毁会话,清除用户登录状态 req.session.destroy(); res.redirect('/login'); });
额外注意事项
- 确保你已经配置了会话管理(比如
express-session),并且生产环境下不要用内存存储会话(建议用Redis等持久化存储) - ID Token有过期时间(默认1小时),如果需要长期保持登录,可以实现Token刷新逻辑
内容的提问来源于stack exchange,提问作者FattyDev1
相关产品推荐
相关产品推荐

