繁体   English   中英

在 angular firebase 应用程序中重置 google reCaptcha v3

[英]Reset google reCaptcha v3 in angular firebase application

最近我们在使用 OTP 的应用程序注册部分遇到了一些问题。 我们使用 firebase 电话身份验证,它使用谷歌 reCaptcha v3。 每当我们发送 OTP 时,它都按预期正常工作,但如果我们想返回 go 并更改号码,或者在再次发送 OTP 的情况下,它会抛出以下错误。

reCaptcha 已在此元素上呈现。

我们已经尝试清除 reCaptcha 验证器,但仍然没有任何效果。 我以前处理过这个问题,但没有考虑过,因为我专注于应用程序的其他部分。

基本上,当您使用来自 reCaptcha 验证程序的.clear()方法时,它将从页面中清除 reCAPTCHA 小部件并销毁当前实例。 这意味着当您在 dom 元素上初始化验证码并在运行clear()方法后,它也会删除验证码实例以及 dom 元素。 您可以在下方查看更改前后的内容。 在我们清除 recaptcha 之前,它正在删除 dom 元素,我们无法重新初始化,因为它不会获取该元素。 此外,如果它已经在某个元素上初始化,则在清除之前无法重新初始化。

signup.component.html:之前

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

signup.component.html:之后

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

注册.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();
  }
}

下面是我们在组件中所做的更改

//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>`;
  }

我希望它也能解决你的问题。 您可以在发现此类问题的任何类型的应用程序上使用相同的逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM