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

如何支持用户名/密码与邮箱/密码两种登录方式?

Firebase 用户名登录匹配邮箱注册用户的解决方案

问题背景

我正尝试简化用户注册流程,不强制要求填写邮箱。用户再次登录时会出现三种情况:

  • 用户未使用邮箱注册,后端将其邮箱设为username@mydomain.com,登录时在用户名后追加@mydomain.com进行认证。
  • 用户使用邮箱注册,直接通过邮箱/密码登录。
  • 用户使用邮箱注册,但尝试通过用户名/密码登录。

针对第三种情况,我找不到合适的认证方法。最初想法是将用户名和密码发送至Cloud Function,匹配用户名对应的邮箱并验证密码,但Admin SDK似乎无此功能。将邮箱返回给客户端又存在安全隐患,请问是否遗漏了什么?有什么解决方案吗?

最终实现方案

我最终采用了建议的方案,通过Cloud Function结合Firestore映射关系与Firebase身份验证API完成验证,避免直接暴露邮箱给客户端,代码如下:

// The Cloud Functions for Firebase SDK to
// create Cloud Functions and set up triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access Firestore.
const admin = require('firebase-admin');
admin.initializeApp();

const axios = require('axios');
const apiKey = 'API KEY';
const signInURL = 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=' + apiKey;

exports.getEmail = functions.https.onCall(async (data, context) => {
  // 获取传入的用户名和密码参数
  const username = data.text.toLowerCase();
  const password = data.password;
  
  // 通过用户名查询对应的UID
  const uidData = await admin
    .firestore()
    .collection('usernameToUid')
    .doc(username)
    .get();
  const uid = uidData.get('uid');
  
  if (uid == null) {
    return {result: 'auth/user-not-found'};
  }
  
  // 通过UID查询对应的邮箱
  const emailData = await admin
    .firestore()
    .collection('emails')
    .doc(uid)
    .get();
  const email = emailData.get('email');
  
  if (email == null) {
    return {result: 'auth/email-not-found'};
  }
  
  // 调用Firebase身份验证API验证密码
  try {
    const response = await axios
      .post(signInURL, {
        email: email,
        password: password,
        returnSecureToken: true,
      });
    return {result: response.data.email};
  } catch (error) {
    return {result: 'auth/incorrect-password'};
  }
});

实现逻辑说明

  1. 在Firestore中维护两个集合:
    • usernameToUid:存储用户名到用户UID的映射,文档ID为用户名,字段包含对应UID
    • emails:存储用户UID到邮箱的映射,文档ID为UID,字段包含用户邮箱
  2. Cloud Function接收客户端传入的用户名和密码,先通过用户名找到对应的UID
  3. 再通过UID找到用户的邮箱
  4. 调用Firebase的signInWithPassword API验证邮箱和密码的正确性,验证通过后返回邮箱,失败则返回对应的错误标识

内容的提问来源于stack exchange,提问作者KnowNothing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:40:54