在angular firebase应用中重置google reCaptcha v3



最近我们在OTP的应用程序注册部分遇到了一些问题。我们使用firebase电话认证,它使用谷歌reCaptcha v3。每当我们发送OTP时,它都像预期的那样工作得很好,但是如果我们想回去更改数字或再次发送OTP,它就会抛出以下错误。

reCaptcha已在此元素上呈现。

我们已经尝试清除reCaptcha验证器,但仍然没有正常工作。我以前曾处理过这个问题,但没有想到,因为我专注于应用程序的其他部分。

基本上当你使用.clear()方法从reCaptcha验证器,它将从页面清除reCaptcha小部件,并破坏当前实例。这意味着当你在dom元素上初始化captcha,并且在你运行clear()方法之后,它将删除captcha实例以及dom元素。您可以在下面看到更改前后的对比。之前,当我们清除recaptcha时,它正在删除dom元素,我们无法重新初始化,因为它不会获得元素。此外,如果它已经在元素上初始化,则在清除之前不能重新初始化。

前signup.component.html:

<div id="captcha-element"></div>

后signup.component.html:

<div #captchaContainer>
<div id="captcha-element"></div>
</div>

signup.component.ts

declare var grecaptcha: any;
@Component({
selector: 'auth-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.scss'],
})
export class LoginComponent implements OnDestroy {

otpIdentifier: string | null = null;
recaptchaVerifier: firebase.auth.RecaptchaVerifier | null = null;
recaptchaWidgetId: number | null = null;

@ViewChild('captchaContainer') captchaContainer!: ElementRef;

constructor() {}

async sendOtp() {
try {
if (!this.phoneNumber) {
return;
}

if (this.recaptchaVerifier && this.isSubmitting && !this.otpSent) {
//send otp here
}
} catch (error: any) {
console.error(error);
} 
}
initiateRecaptchaContainer() {
this.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('captcha-element', {
'size': 'invisible',
'expired-callback': () => {
grecaptcha.reset(this.recaptchaWidgetId);
},
});
this.recaptchaVerifier?.render().then((id) => {
this.recaptchaWidgetId = id;
});
}
async resendOtp() {
this.clearRecaptcha();
this.initiateRecaptchaContainer();
if (this.recaptchaVerifier) {
//send otp here
}
}
clearRecaptcha() {
this.recaptchaVerifier?.clear();
this.captchaContainer.nativeElement.innerHTML = `<div id="captcha-element"></div>`;
}
returnAndReinitializeCaptcha() {
this.clearRecaptcha();
this.initiateRecaptchaContainer();
}
ngOnDestroy(): void {
}
ngAfterViewInit(): void {
this.initiateRecaptchaContainer();
}
}
下面是我们在component 中所做的更改
//to clear the captcha and adding the element to dom again so that we can reinitialize the captcha.
@ViewChild('captchaContainer') captchaContainer!: ElementRef;
clearRecaptcha() {
this.recaptchaVerifier?.clear();
this.captchaContainer.nativeElement.innerHTML = `<div id="captcha-element"></div>`;
}
我希望这也能解决你的问题。您可以在发现此类问题的任何类型的应用程序上使用相同的逻辑。

最新更新