Phone-Authenticated 用户的 Firebase 重新验证和电子邮件链接
Firebase Re-authentication & email Linking for Phone-Authenticated Users
用户注册时,使用Phone授权。使用一段时间后,建议link 一个(电子邮件和密码) 到他们现有的帐户。
linking 过程因错误 (auth/requires-recent-login) 而失败。我的代码如下。
// The following generates the error: [auth/requires-recent-login] This operation is sensitive and requires recent authentication. Log in again before retrying this request.
const emailCredential = firebase.auth.EmailAuthProvider.credential(state.email, state.password);
const newCredential = await firebase.auth().currentUser.linkWithCredential(emailCredential);
要修复此错误,我知道我需要在 linking 之前调用 reauthenticateWithCredential()。但是,我不想让用户重新登录(接收并输入验证码。)这完全可能吗?
我尝试将 currentUser.getIdToken(true)
的结果传递给 PhoneAuthProvider.credential()
我不确定这是否正确。无论如何,它生成了一个错误(无法在没有 verificationProof、sessionInfo、临时证明或注册 ID 的情况下创建 PhoneAuthCredntial。)。
我的代码如下。
// The following works:
const accessToken = await firebase.auth().currentUser.getIdToken(true);
// The following works:
const currentCredential = firebase.auth.PhoneAuthProvider.credential(accessToken);
// The following generates the error: Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, temporary proof, or enrollment ID.
const abc = await firebase.auth().currentUser.reauthenticateWithCredential(currentCredential);
// The following is never reached:
const emailCredential = firebase.auth.EmailAuthProvider.credential(state.email, state.password);
const newCredential = await firebase.auth().currentUser.linkWithCredential(emailCredential);
感谢您付出的努力和时间来帮助我...
重要信息:
- firebase.auth().currentUser.reauthenticateWithCredential(credential) 需要属性 credential
- 对于使用 Phone 号码登录的用户,我无法在需要时找到获取此凭据的方法 。 顺便说一句,有可能为使用其他提供商登录的用户获取它,例如Facebook。
- 但是,对于使用 phone 号码登录的用户,有可能在登录过程中 获得此凭据。 检查 https://firebase.google.com/docs/auth/web/phone-auth .
- 因此,我决定在登录过程中将用户的凭据保存在他们的设备上。为此,我正在使用 Redux 和 Redux-Persist。
修复后的我的代码。
// This is an extract from the login script:
firebase.auth().signInWithPhoneNumber(phoneNo)
.then(confirmResult => {
dispatch({ type: "PhoneNo_accepted", payload: { confirmResult: confirmResult } });
})
.catch(error => {
dispatch({ type: "display_message", payload: { messageText: `Phone Number Error: ${error.message}` } });
});
// Change#1. The following statement is a NEW step, which I added to get the credential during the login process.
const credential = firebase.auth.PhoneAuthProvider.credential(state.confirmResult.verificationId, state.codeInput);
state.confirmResult.confirm(state.codeInput)
.then( (user) => {
// Change#2. The following function would save the credential to the app's state, e.g. using Redux
_onAuthComplete(user, credential);
})
.catch( error => {
dispatch({ type: "display_message", payload: { messageText: `Verification Code Error: ${error.message}` } });
});
// // //
// This is an extract from the linking script:
// Change#3. props.credential is the credential, which was saved to the app's state.
await firebase.auth().currentUser.reauthenticateWithCredential(props.credential);
const emailCredential = firebase.auth.EmailAuthProvider.credential(state.email, state.password);
const newCredential = await firebase.auth().currentUser.linkWithCredential(emailCredential);
用户注册时,使用Phone授权。使用一段时间后,建议link 一个(电子邮件和密码) 到他们现有的帐户。
linking 过程因错误 (auth/requires-recent-login) 而失败。我的代码如下。
// The following generates the error: [auth/requires-recent-login] This operation is sensitive and requires recent authentication. Log in again before retrying this request.
const emailCredential = firebase.auth.EmailAuthProvider.credential(state.email, state.password);
const newCredential = await firebase.auth().currentUser.linkWithCredential(emailCredential);
要修复此错误,我知道我需要在 linking 之前调用 reauthenticateWithCredential()。但是,我不想让用户重新登录(接收并输入验证码。)这完全可能吗?
我尝试将 currentUser.getIdToken(true)
的结果传递给 PhoneAuthProvider.credential()
我不确定这是否正确。无论如何,它生成了一个错误(无法在没有 verificationProof、sessionInfo、临时证明或注册 ID 的情况下创建 PhoneAuthCredntial。)。
我的代码如下。
// The following works:
const accessToken = await firebase.auth().currentUser.getIdToken(true);
// The following works:
const currentCredential = firebase.auth.PhoneAuthProvider.credential(accessToken);
// The following generates the error: Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, temporary proof, or enrollment ID.
const abc = await firebase.auth().currentUser.reauthenticateWithCredential(currentCredential);
// The following is never reached:
const emailCredential = firebase.auth.EmailAuthProvider.credential(state.email, state.password);
const newCredential = await firebase.auth().currentUser.linkWithCredential(emailCredential);
感谢您付出的努力和时间来帮助我...
重要信息:
- firebase.auth().currentUser.reauthenticateWithCredential(credential) 需要属性 credential
- 对于使用 Phone 号码登录的用户,我无法在需要时找到获取此凭据的方法 。 顺便说一句,有可能为使用其他提供商登录的用户获取它,例如Facebook。
- 但是,对于使用 phone 号码登录的用户,有可能在登录过程中 获得此凭据。 检查 https://firebase.google.com/docs/auth/web/phone-auth .
- 因此,我决定在登录过程中将用户的凭据保存在他们的设备上。为此,我正在使用 Redux 和 Redux-Persist。
修复后的我的代码。
// This is an extract from the login script:
firebase.auth().signInWithPhoneNumber(phoneNo)
.then(confirmResult => {
dispatch({ type: "PhoneNo_accepted", payload: { confirmResult: confirmResult } });
})
.catch(error => {
dispatch({ type: "display_message", payload: { messageText: `Phone Number Error: ${error.message}` } });
});
// Change#1. The following statement is a NEW step, which I added to get the credential during the login process.
const credential = firebase.auth.PhoneAuthProvider.credential(state.confirmResult.verificationId, state.codeInput);
state.confirmResult.confirm(state.codeInput)
.then( (user) => {
// Change#2. The following function would save the credential to the app's state, e.g. using Redux
_onAuthComplete(user, credential);
})
.catch( error => {
dispatch({ type: "display_message", payload: { messageText: `Verification Code Error: ${error.message}` } });
});
// // //
// This is an extract from the linking script:
// Change#3. props.credential is the credential, which was saved to the app's state.
await firebase.auth().currentUser.reauthenticateWithCredential(props.credential);
const emailCredential = firebase.auth.EmailAuthProvider.credential(state.email, state.password);
const newCredential = await firebase.auth().currentUser.linkWithCredential(emailCredential);