如何使用Firebase Auth对接独立后端实现用户身份校验?
实现方案总览
你可以通过Firebase官方提供的ID Token(标准JWT格式)完成前后端身份打通,完全可以拦截Postman等未授权的直接接口调用,同时可靠获取用户唯一标识和身份信息。
步骤1:前端获取Firebase签发的JWT令牌
你现有代码中拿到的是Google API访问用的Access Token,不是用于自有后端校验的凭证,需要额外获取Firebase Auth签发的ID Token,修改后的登录代码如下:
const signIn = () => { return signInWithPopup(auth, provider) .then(async (result) => { // The signed-in user info. const user = result.user; // 核心:获取Firebase私钥签发的JWT格式ID Token,专门用于后端身份校验 const idToken = await user.getIdToken(); // 自行存储到localStorage、全局状态管理工具中即可 localStorage.setItem('firebase_id_token', idToken); // 前端直接可以拿到用户唯一ID,和后端校验后返回的uid完全一致 const uid = user.uid; console.log("用户uid:", uid, "ID Token:", idToken, "用户信息:", user); }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.email; // The AuthCredential type that was used. const credential = GoogleAuthProvider.credentialFromError(error); console.log(errorCode, errorMessage, credential, email); }); };
手机号登录的逻辑完全一致,用户完成验证码校验拿到user对象后,同样调用user.getIdToken()获取令牌即可。
步骤2:前端请求接口统一携带令牌
所有向后端发起的请求,都在请求头中携带该令牌,以axios为例可以通过请求拦截器统一处理:
import axios from 'axios'; const request = axios.create({ baseURL: '你的后端服务根地址' }); // 请求拦截器统一注入身份令牌 request.interceptors.request.use(config => { const token = localStorage.getItem('firebase_id_token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; });
步骤3:后端集成Firebase Admin SDK校验令牌
这是拦截未授权访问的核心逻辑,仅需在后端引入Firebase Admin SDK,对所有受保护接口的请求头令牌做校验即可:
- 先在Firebase控制台获取服务账号密钥文件,存储到后端服务的加密环境变量中,绝对不能泄露到前端
- 编写统一的身份校验中间件,所有受保护接口都先经过该中间件校验
以下是Node.js环境的示例代码,Java、Python、Go等其他后端语言都有对应官方SDK,逻辑完全一致:
const admin = require('firebase-admin'); // 初始化Firebase Admin SDK const serviceAccount = require(process.env.FIREBASE_ADMIN_KEY_PATH); admin.initializeApp({ credential: admin.credential.cert(serviceAccount) }); // 身份校验中间件 const authValidateMiddleware = async (req, res, next) => { const authHeader = req.headers.authorization; // 无令牌直接返回401 if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).json({ msg: '未授权访问' }); } const idToken = authHeader.split(' ')[1]; try { // 自动校验令牌签名、有效期、签发方,伪造、过期、篡改的令牌都会直接抛出错误 const decodedToken = await admin.auth().verifyIdToken(idToken); // 校验通过后即可拿到用户的所有身份信息,挂载到请求对象供后续业务逻辑使用 req.currentUser = { uid: decodedToken.uid, // 用户全局唯一ID,和前端拿到的uid完全一致 email: decodedToken.email, phoneNumber: decodedToken.phone_number, emailVerified: decodedToken.email_verified }; next(); } catch (err) { return res.status(401).json({ msg: '令牌无效或已过期' }); } }; // 受保护的业务接口使用中间件即可 app.get('/api/user/orders', authValidateMiddleware, (req, res) => { const userId = req.currentUser.uid; // 后续业务逻辑... res.json({ data: '业务数据' }); });
关键注意事项
- Firebase ID Token 默认有效期为1小时,前端可以通过
onIdTokenChanged事件监听令牌变化自动刷新,无需用户重新登录 - 不要使用Google/短信服务商的原生Access Token做后端校验,仅Firebase签发的ID Token可以被可靠校验
- 服务账号密钥属于最高级敏感信息,仅可存储在后端加密环境变量中,禁止硬编码、禁止提交到代码仓库
内容的提问来源于stack exchange,提问作者CodeOfPrince
相关产品推荐
相关产品推荐

