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

Firebase邮箱/密码认证:如何要求邮箱验证并配置未验证时不返回Bearer Token?

Firebase邮箱/密码认证:未验证邮箱时阻止返回Bearer Token的方案

好问题!我对Firebase Auth这块熟得很,直接给你说结论:Firebase邮箱/密码认证提供程序没有开箱即用的配置项,能让用户未完成邮箱验证时就阻止返回Bearer Token并返回403错误。

为什么没有这个默认配置?

Firebase Auth的设计逻辑和Cognito不一样:邮箱验证在Firebase里是一个额外的用户状态标记,而非登录的前置条件。只要用户输入正确的邮箱和密码,不管邮箱是否验证,系统都会正常颁发ID Token(也就是你说的Bearer Token)。这个设计是为了支持一些不需要强制验证邮箱的场景,比如允许用户先体验部分功能,再引导验证。

替代方案:不用写复杂处理函数也能实现类似效果

虽然没有直接的开关,但有几种简洁的方式可以达到类似Cognito的强制验证效果:

  • 用Cloud Functions自定义登录逻辑
    放弃直接调用signInWithEmailAndPassword,让前端调用一个Cloud Functions的Callable函数,在函数里先检查用户的邮箱验证状态,只有验证通过才生成自定义令牌返回给前端,前端再用signInWithCustomToken登录。未验证的用户会在函数层被拦截,直接返回403。
    示例函数代码:

    const functions = require("firebase-functions");
    const admin = require("firebase-admin");
    admin.initializeApp();
    
    exports.signInWithVerifiedEmail = functions.https.onCall(async (data, context) => {
      const { email, password } = data;
      try {
        // 先验证账号密码有效性
        const userRecord = await admin.auth().getUserByEmail(email);
        // 检查邮箱是否已验证
        if (!userRecord.emailVerified) {
          throw new functions.https.HttpsError("permission-denied", "请先验证邮箱");
        }
        // 生成自定义令牌供前端登录
        const customToken = await admin.auth().createCustomToken(userRecord.uid);
        return { token: customToken };
      } catch (error) {
        throw new functions.https.HttpsError("invalid-argument", error.message);
      }
    });
    
  • 用Security Rules保护核心资源
    如果你主要是想阻止未验证用户访问Firebase的核心资源(比如Firestore、Storage),直接在Security Rules里添加邮箱验证检查即可。这样即使用户拿到了Token,也无法访问受保护的资源,效果和强制验证登录差不多。
    示例Firestore规则:

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /{document=**} {
          allow read, write: if request.auth != null && request.auth.token.email_verified == true;
        }
      }
    }
    
  • 前端/后端拦截未验证用户
    可以在前端路由守卫或者后端API拦截器里,检查登录用户的emailVerified状态,如果为false就强制登出并返回403提示。比如前端用React的路由守卫:

    import { getAuth, onAuthStateChanged, signOut } from "firebase/auth";
    
    const auth = getAuth();
    onAuthStateChanged(auth, (user) => {
      if (user && !user.emailVerified) {
        signOut(auth);
        alert("请先验证邮箱才能登录");
        // 跳转到验证引导页
        window.location.href = "/verify-email";
      }
    });
    

总结

Firebase确实没有开箱即用的配置来直接阻止未验证用户获取Token,但通过上面几种方式,不需要写太多复杂的处理逻辑就能实现类似Cognito的强制邮箱验证效果,其中Cloud Functions的方式最接近你想要的“认证环节拦截”需求,而Security Rules则是保护资源最省心的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:19:06