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

Firebase重置密码:如何拦截流程以禁用历史密码?

用Cloud Functions实现Firebase密码重置时禁用历史密码

明确说:Firebase原生的密码重置流程(邮件链接类型)没法直接拦截它的内置重置函数,但完全可以用Cloud Functions配合自定义逻辑实现历史密码校验的需求,具体方案如下:

核心思路

Firebase密码重置最终会触发用户密码更新,我们可以监听这个密码更新事件,在密码变更完成后校验新密码是否属于历史哈希;或者自定义部分重置流程,提前完成校验逻辑。

具体实现步骤

1. 存储用户历史密码哈希

  • 用户每次设置/修改密码时,把密码的哈希值存储到Firebase数据库(Firestore或实时数据库均可),与用户UID关联绑定。
  • 重点:绝对不能存储明文密码,建议使用Firebase Auth自带的scrypt哈希算法,通过Cloud Functions获取用户的密码哈希参数,生成与系统一致的哈希值。

2. 用Cloud Functions监听密码更新事件

通过onUserUpdated触发器监听用户密码变更动作,触发后执行历史密码校验:

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

exports.checkHistoryPassword = functions.auth.user().onUserUpdated(async (change, context) => {
  const newUser = change.after;
  const oldUser = change.before;

  // 仅当密码确实发生变更时执行校验
  if (newUser.passwordHash !== oldUser.passwordHash) {
    const uid = newUser.uid;
    // 从数据库拉取该用户的历史哈希列表
    const userHistoryRef = admin.firestore().collection("userPasswordHistory").doc(uid);
    const historyDoc = await userHistoryRef.get();
    
    if (historyDoc.exists) {
      const storedHashes = historyDoc.data().hashes;
      // 检查新密码哈希是否存在于历史列表中
      if (storedHashes.includes(newUser.passwordHash)) {
        // 匹配到历史密码,强制回滚至原密码
        await admin.auth().updateUser(uid, {
          passwordHash: oldUser.passwordHash,
          passwordSalt: oldUser.passwordSalt
        });
        functions.logger.error(`用户 ${uid} 尝试使用历史密码,已执行回滚`);
      } else {
        // 新密码合法,将哈希加入历史列表
        await userHistoryRef.set({
          hashes: admin.firestore.FieldValue.arrayUnion(newUser.passwordHash)
        }, { merge: true });
      }
    } else {
      // 用户首次设置密码,初始化历史哈希列表
      await userHistoryRef.set({
        hashes: [newUser.passwordHash]
      });
    }
  }
});

3. 可选:自定义密码重置流程

如果想在用户输入新密码时实时完成校验(避免事后回滚的体验问题),可以放弃Firebase原生的重置邮件链接,改为:

  • 发送自定义重置邮件,内含带过期时间的自定义令牌(存储在数据库中)。
  • 用户访问自定义重置页面,输入新密码后先调用Cloud Functions校验哈希是否在历史列表中。
  • 校验通过后,再调用admin.auth().updateUser()更新密码,同时更新历史哈希列表。

关键注意事项

  • 配置数据库安全规则,确保只有用户本人或授权管理员能访问历史哈希数据。
  • 必须使用Firebase Auth原生哈希算法,避免自定义哈希导致与系统生成值不一致。
  • 处理并发场景,比如用户快速多次修改密码时,保证哈希列表更新逻辑不冲突。

内容的提问来源于stack exchange,提问作者Mahesh H Viraktamath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:10:23