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
相关产品推荐
相关产品推荐

