【发布时间】:2020-12-06 11:13:36
【问题描述】:
我正在我的应用上编写“删除帐户”功能,我希望用户在触发删除之前再次输入他们的密码。
实现这一点的最佳方法是什么?我正在考虑使用“signInWithEmailAndPassword”方法并捕获结果以检查凭据是否正确,但我担心这会覆盖当前会话。
有什么建议吗?
【问题讨论】:
标签: javascript angular angularfire user-management
我正在我的应用上编写“删除帐户”功能,我希望用户在触发删除之前再次输入他们的密码。
实现这一点的最佳方法是什么?我正在考虑使用“signInWithEmailAndPassword”方法并捕获结果以检查凭据是否正确,但我担心这会覆盖当前会话。
有什么建议吗?
【问题讨论】:
标签: javascript angular angularfire user-management
如果会话太旧或其他什么,“删除帐户”功能无论如何都会引发错误。然后,您需要重新验证用户。还有一个特殊功能:reauthenticateWithCredential()。
这里我有一个例子来展示登录和重新验证功能的区别(从我的一个项目中复制并减少了一点,因为有一些分析和东西):
public async reAuthenticate(user: User, { email, password }: IEmailLoginData): Promise<UserCredential> {
const credentials = firebase.auth.EmailAuthProvider.credential(email, password);
return user.reauthenticateWithCredential(credentials)
.catch(e => {
console.error(e);
throw e;
});
}
public async login({ email, password }: IEmailLoginData): Promise<UserCredential> {
return firebase.auth().signInWithEmailAndPassword(email, password)
.catch(e => {
console.error(e);
throw e;
});
}
// PS: IEmailLoginData is a custom interface from me, but it just contains email and password
此外,这里是“删除帐户”的代码。它应该是不言自明的 - 希望它有点帮助:
async delete(): Promise<void> {
const dialogRef = this.dialog.open(YesNoDialogComponent, {
data: {
yes: 'Yes',
no: 'No',
title: 'Are you sure that you want to delete your account?'
}
});
const result = await dialogRef.afterClosed().pipe(take(1)).toPromise();
if (result === IYesNoDialogResult.YES) {
try {
const authUser = await this.auth.nextAuthUser(); // Getting the current firebase user from my custom service
await authUser.delete();
await this.router.navigateByUrl('login');
} catch(e) {
const toast = await this.toast.create({
duration: 3000,
message: 'This is a sensitive operation. Please login again to do this'
});
await toast.present();
await this.router.navigateByUrl('reauth');
});
}
}
对于不同的身份验证提供者,它可能会略有不同,但本质上还是一样的。仅以 google 为例(如果您想使用 Ionic Native Google Plus 登录插件),您需要从插件结果中创建重新验证凭据:
public async reAuthenticate(user: User): Promise<UserCredential> {
try {
if (this.platform.is('cordova')) {
try {
const gUser = await this.gPlus.login({
webClientId: environment.googleWebClientId,
offline: true,
scopes: 'profile email'
});
const credential = firebase.auth.GoogleAuthProvider.credential(gUser.idToken);
return await user.reauthenticateWithCredential(credential);
} catch (nativeE) { // If login failed via native method, fallback to redirects
if (nativeE == 12501 || nativeE == 13) { // User cancelled login
return null;
}
console.error(nativeE);
// In constructor:
// this._provider = new firebase.auth.GoogleAuthProvider();
await user.reauthenticateWithRedirect(this._provider);
return await firebase.auth().getRedirectResult();
}
}
else {
return await user.reauthenticateWithPopup(this._provider);
}
} catch (e) {
console.error(e);
throw e;
}
}
【讨论】:
const credentials = firebase.auth.EmailAuthProvider.credential(email, password); 部分换成合适的对应部分。我在我的答案中附加了一个例子。 @dev_huesca