Firebase多因素认证遇auth/code-expired错误求助
Firebase多因素认证短信验证码提示过期问题排查
我正在为Web应用集成Firebase多因素认证,按官方文档流程操作,前面步骤均正常,但到短信验证环节时,刚收到验证码就输入,却持续触发FirebaseError: Firebase: Error (auth/code-expired)错误。这是我首次使用Firebase,附上相关代码(已隐去真实手机号),恳请协助排查原因。
signInWithEmailAndPassword(auth, email, password) .then((userCredential) => { console.log('Sign in Success'); navigate("/Search"); }) .catch(function (error) { if (error.code === 'auth/multi-factor-auth-required') { console.log('MFA required'); const resolver = getMultiFactorResolver(auth, error); const selectedIndex = 0; if (resolver.hints[selectedIndex].factorId === PhoneMultiFactorGenerator.FACTOR_ID) { console.log(resolver.hints[selectedIndex].factorId); const phoneNumber = "XXXXXXXX"; console.log(resolver.session); const phoneInfoOptions = { multiFactorHint: resolver.hints[selectedIndex], session: resolver.session }; const phoneAuthProvider = new PhoneAuthProvider(auth); console.log(phoneAuthProvider); // Create recaptchaVerifier instance const recaptchaVerifier = new RecaptchaVerifier( "recaptcha-container", { size: "normal", callback: function (response) { // reCAPTCHA resolved, continue with phone verification phoneAuthProvider.verifyPhoneNumber(phoneNumber, recaptchaVerifier, { // Set the code expiration duration to 60 seconds codeTime: 60000 }) .then(function (verificationId) { // Ask user for the SMS verification code. Then: const verificationCode = prompt("Enter the verification code"); const cred = PhoneAuthProvider.credential(verificationId, verificationCode); console.log(cred) const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred); // Complete sign-in. return resolver.resolveSignIn(multiFactorAssertion); }) .then(function (userCredential) { navigate("/Search"); }) .catch(function (error) { console.log(error) }); }, "expired-callback": function () { // Response expired. Ask user to solve reCAPTCHA again. // ... }, }, auth ); recaptchaVerifier.render().then(function (widgetId) { window.recaptchaWidgetId = widgetId; }); } } });
排查关键点及修复方案
- 错误传递验证参数:MFA流程中,
verifyPhoneNumber需要传入包含session和multiFactorHint的phoneInfoOptions对象,而非直接传手机号。当前代码中已构建phoneInfoOptions但未使用,导致验证流程未关联MFA会话,引发过期错误。 - 有效期参数名错误:
codeTime不是Firebase的合法参数,正确参数为timeout(单位毫秒)。错误参数会导致Firebase忽略自定义有效期设置,甚至引发流程异常。 - 阻塞式输入影响会话:
prompt会阻塞主线程,可能导致MFA会话超时,建议改用自定义UI输入框替代。
修正后的核心代码片段
// 修正verifyPhoneNumber的参数和有效期设置 phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier, { timeout: 60000 // 正确设置验证码有效期为60秒 }) .then(function (verificationId) { // 替换prompt为自定义输入UI,避免阻塞主线程 const verificationCode = prompt("Enter the verification code"); const cred = PhoneAuthProvider.credential(verificationId, verificationCode); const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred); return resolver.resolveSignIn(multiFactorAssertion); }) .then(function (userCredential) { navigate("/Search"); }) .catch(function (error) { console.log(error); });
内容的提问来源于stack exchange,提问作者Valon Cazimi
相关产品推荐
相关产品推荐

