如何在Firebase中实现手机号注册后用手机号+密码的后续登录?
Firebase手机号+密码登录实现方案(基于Phone Auth体系)
Firebase原生手机号认证仅支持OTP验证,要实现手机号+密码登录,需结合Firestore存储的用户数据与自定义认证逻辑,核心思路是通过密码验证后生成Firebase自定义Token完成会话登录,具体步骤如下:
一、调整注册流程,绑定Auth用户与Firestore数据
用户完成OTP验证后,Firebase Auth会自动创建用户并生成唯一uid,此时需补充以下操作:
- 对用户设置的密码进行哈希加密(推荐用
bcrypt或类似算法,绝对禁止明文存储); - 将
uid、手机号、加密密码、用户名存入Firestore的「users」集合(以uid作为文档ID更便于后续关联)。
二、实现手机号+密码登录的核心逻辑
登录流程需通过后端(推荐用Firebase Cloud Functions)封装验证逻辑,避免前端直接操作敏感数据:
- 前端收集用户输入的手机号和密码,调用Cloud Functions的登录接口;
- 后端接口根据手机号查询Firestore「users」集合,获取对应用户的加密密码和
uid; - 比对用户输入的密码与存储的哈希密码,验证通过后生成对应
uid的Firebase自定义Token; - 前端拿到自定义Token后,调用
signInWithCustomToken方法完成Firebase Auth登录,建立会话。
三、关键代码示例
1. 注册用户的Cloud Functions(处理加密与存储)
const functions = require("firebase-functions"); const admin = require("firebase-admin"); const bcrypt = require("bcrypt"); admin.initializeApp(); exports.registerUser = functions.https.onCall(async (data) => { const { phoneNumber, password, username, uid } = data; const saltRounds = 10; // 加密密码 const hashedPassword = await bcrypt.hash(password, saltRounds); // 存入Firestore await admin.firestore().collection("users").doc(uid).set({ phoneNumber, hashedPassword, username, uid }); return { success: true }; });
2. 手机号+密码登录的Cloud Functions(验证与生成Token)
exports.loginWithPhonePassword = functions.https.onCall(async (data) => { const { phoneNumber, password } = data; // 查询用户 const userQuery = await admin.firestore() .collection("users") .where("phoneNumber", "==", phoneNumber) .get(); if (userQuery.empty) { throw new functions.https.HttpsError("not-found", "用户不存在"); } const userData = userQuery.docs[0].data(); // 验证密码 const isValidPassword = await bcrypt.compare(password, userData.hashedPassword); if (!isValidPassword) { throw new functions.https.HttpsError("unauthenticated", "密码错误"); } // 生成自定义Token const customToken = await admin.auth().createCustomToken(userData.uid); return { customToken }; });
3. 前端登录调用逻辑
// 初始化Firebase后调用 const handleLogin = async (phone, password) => { const loginFn = firebase.functions().httpsCallable("loginWithPhonePassword"); try { const res = await loginFn({ phoneNumber: phone, password }); await firebase.auth().signInWithCustomToken(res.data.customToken); console.log("登录成功"); // 跳转至首页或其他业务逻辑 } catch (err) { alert(err.message); } };
四、安全注意事项
- 禁止前端直接查询Firestore用户集合,所有数据查询与密码验证必须通过Cloud Functions完成;
- 密码哈希加密操作应在后端执行,避免前端泄露加密逻辑;
- 确保所有请求通过HTTPS传输,防止数据被窃听。
内容的提问来源于stack exchange,提问作者Sachin Aphro ECS
相关产品推荐
相关产品推荐

