如何在Node.js服务器端获取Firebase已登录用户信息?
解决方案
Firebase Web SDK 默认不会自动把用户的ID令牌存入Cookie,它通常将令牌存在浏览器的localStorage或IndexedDB中,仅在向Firebase服务发起请求时自动携带。要在你的Node.js服务器端校验用户,需要手动处理令牌的传递与验证,步骤如下:
1. 客户端:登录后获取并传递令牌
用户通过signInWithEmailAndPassword登录成功后,调用getIdToken()获取当前用户的ID令牌,之后可以通过两种方式传递给服务器:
方式一:存入Cookie(推荐用于会话式场景)
登录成功后,将令牌写入HttpOnly Cookie,提升安全性:
// 登录成功后的回调 firebase.auth().signInWithEmailAndPassword(email, password) .then((userCredential) => { const user = userCredential.user; return user.getIdToken(); }) .then((idToken) => { // 发送请求到你的服务器,让服务器设置Cookie fetch('/api/set-token', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ idToken }), }); });
你的Node.js服务器收到令牌后,设置HttpOnly Cookie:
// Express示例 app.post('/api/set-token', async (req, res) => { const { idToken } = req.body; // 设置Cookie,配置安全属性 res.cookie('firebase-token', idToken, { httpOnly: true, secure: process.env.NODE_ENV === 'production', // 生产环境启用HTTPS sameSite: 'strict', maxAge: 3600000, // 1小时,和ID令牌有效期一致 }); res.sendStatus(200); });
方式二:每次请求携带在请求头中
适合API接口场景,每次发起请求时在Authorization头里带上令牌:
// 发起请求前获取令牌并携带 async function fetchProtectedData() { const user = firebase.auth().currentUser; if (user) { const idToken = await user.getIdToken(); const response = await fetch('/api/protected', { headers: { 'Authorization': `Bearer ${idToken}`, }, }); const data = await response.json(); // 处理数据 } }
2. 服务器端:验证令牌并获取用户信息
使用firebase-admin库验证ID令牌的有效性,获取用户UID后,即可查询你的SQL数据库校验用户:
首先初始化firebase-admin:
const admin = require('firebase-admin'); const serviceAccount = require('./path-to-service-account-key.json'); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), });
然后在接口中验证令牌:
// Express示例,处理受保护的API app.get('/api/protected', async (req, res) => { // 从Cookie或请求头获取令牌 const idToken = req.cookies['firebase-token'] || req.headers.authorization?.split(' ')[1]; if (!idToken) { return res.status(401).send('未提供认证令牌'); } try { // 验证令牌 const decodedToken = await admin.auth().verifyIdToken(idToken); const uid = decodedToken.uid; // 用UID查询你的SQL数据库,获取用户信息 // 示例:假设你用mysql2 const [user] = await connection.query('SELECT * FROM users WHERE firebase_uid = ?', [uid]); if (!user.length) { return res.status(404).send('用户不存在'); } // 后续业务逻辑 res.json({ user: user[0] }); } catch (error) { console.error('令牌验证失败:', error); res.status(403).send('无效的认证令牌'); } });
额外注意事项
- 令牌刷新:Firebase ID令牌有效期为1小时,客户端需要监听
onIdTokenChanged事件,在令牌刷新时更新Cookie或请求头,避免请求失败。 - 安全配置:Cookie务必开启
HttpOnly防止XSS攻击,生产环境开启Secure确保仅通过HTTPS传输,SameSite设置为strict或lax防止CSRF。 - 无需Firestore:整个流程不需要依赖Firestore,完全适配你的SQL数据库架构。
内容的提问来源于stack exchange,提问作者chrispytoes
相关产品推荐
相关产品推荐

