Angularfire检查密码

问题描述

我正在为我的应用编写“删除帐户”功能,我希望用户在触发删除操作之前再次输入密码

实现此目标的最佳方法是什么?我当时正在考虑使用“ signInWithEmailAndPassword”方法并捕获结果以检查凭据是否正确,但是恐怕会覆盖当前会话。

有什么提示吗?

解决方法

如果会话太旧或其他原因,则“删除帐户”功能仍会引发错误。然后,您需要重新验证用户。也有一个特殊功能: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;
    }
}