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

Firebase中使用操作码后跨浏览器无法获取当前用户,如何更新用户?

问题解决与流程优化方案

一、当前代码的临时修复(保留原流程但解决跨浏览器问题)

跨浏览器点击链接时auth.currentUser为null,是因为新浏览器没有之前创建用户的会话。可以在applyActionCode成功后,用提取到的邮箱和临时密码重新登录,获取用户实例后再执行更新操作:

let oobCode = window.location.href.split('oobCode=')[1].split('&')[0];
const email = window.location.href.split('email=')[1].split('/')[0];

await applyActionCode(auth, oobCode)
  .then(async () => {
    // 用邮箱和加密后的临时密码重新登录
    const userCredential = await signInWithEmailAndPassword(auth, email, bcrypt.hashSync(email, 6));
    const user = userCredential.user;
    
    await Promise.all([
      updateProfile(user, {displayName: `${firstName} ${lastName}`}),
      updatePassword(user, password),
    ]);
    
    await setUser('local', undefined, user);
    console.log('Welcome', firstName, lastName);
  })

但此方案仍存在临时密码的安全隐患(基于邮箱生成的密码可被逆向推测),更推荐以下优化流程。

二、彻底消除安全隐患的优化流程

改用Firebase邮箱链接登录能力,完全去掉临时密码,同时解决跨浏览器问题:

第一步:收集邮箱并发送注册验证链接

无需提前创建用户,直接发送带登录验证的邮件:

const actionCodeSettings = {
  url: `${window.location.origin}/complete-registration`, // 第二步页面地址
  handleCodeInApp: true,
};

await sendSignInLinkToEmail(auth, email.value, actionCodeSettings)
  .then(() => {
    // 将邮箱暂存到localStorage,供第二步页面使用
    localStorage.setItem('pending-reg-email', email.value);
    loading = false;
    navigate('/verifyEmail');
  })
  .catch((error) => {
    log.error(`Error sending verification email: ${error}`);
    errorMessage = error.message;
    isEmailInvalid = true;
    loading = false;
  });

第二步:验证链接并完成注册(设置密码与姓名)

用户点击链接后,在第二步页面验证链接并自动创建/登录用户,再完成信息更新:

// 检查当前URL是否为邮箱登录验证链接
if (isSignInWithEmailLink(auth, window.location.href)) {
  let email = localStorage.getItem('pending-reg-email');
  // 若localStorage无数据,从URL提取邮箱
  if (!email) {
    email = new URL(window.location.href).searchParams.get('email');
  }

  // 通过链接登录,自动创建新用户(若邮箱未注册)
  const userCredential = await signInWithEmailLink(auth, email, window.location.href);
  const user = userCredential.user;

  // 更新用户姓名与密码
  await Promise.all([
    updateProfile(user, {displayName: `${firstName} ${lastName}`}),
    updatePassword(user, password),
  ]);

  await setUser('local', undefined, user);
  // 清除暂存的邮箱
  localStorage.removeItem('pending-reg-email');
}

优化流程的优势

  • 无安全隐患:全程无需使用临时密码,最终密码由用户自主设置。
  • 跨浏览器兼容:signInWithEmailLink会在当前浏览器创建用户会话,无需依赖原浏览器的会话数据,用户实例可正常获取。
  • 符合官方最佳实践:利用Firebase原生能力减少自定义逻辑,降低漏洞风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:35:49