reCAPTCHA容器未找到或已包含内部元素

时间:2017-07-21 07:06:58

标签: angular authentication angularfire2

当我尝试进行手机验证时,我在角度4中收到错误。

我在控制台中遇到此错误

  

未找到reCAPTCHA容器或已包含内部元素!

我在网上看不到reCAPTCHA容器,也无法按下它。

登录-page.ts

 import { Component, OnInit } from '@angular/core';
// tslint:disable-next-line:quotemark
import { Router } from "@angular/router";
// tslint:disable-next-line:quotemark
import { AuthService } from "../../core/auth.service";

import { ReactiveFormsModule } from '@angular/forms';
import * as firebase from 'firebase';


export class PhoneNumber {

  country: string;

  area: string;

  prefix: string;

  line: string;

  // format phone numbers as E.164

  get e164() {

    const num = this.country + this.area + this.prefix + this.line

    return `+${num}`

  }


}

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'user-login',
  templateUrl: './user-login.component.html',
  styleUrls: ['./user-login.component.scss']
})
export class UserLoginComponent implements OnInit {

  // phone auth
  windowRef: any;
  phoneNumber = new PhoneNumber();
  verificationCode: string;


  user: any;
  constructor(public auth: AuthService,
              private router: Router) { 

              }


  ngOnInit() {
    this.windowRef = this.auth.windowRef
    this.windowRef.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container')
    this.windowRef.recaptchaVerifier.render()


  }

  // phone auth
   sendLoginCode() {


    const appVerifier = this.windowRef.recaptchaVerifier;


    const num = this.phoneNumber.e164;

    console.log(num);
    firebase.auth().signInWithPhoneNumber(num, appVerifier)

            .then(result => {


                this.windowRef.confirmationResult = result;


            })

            .catch( error => console.log(error) );


  }

  verifyLoginCode() {

    this.windowRef.confirmationResult

                  .confirm(this.verificationCode)

                  .then( result => {


                    this.user = result.user;


    })

    .catch( error => console.log(error, 'Incorrect code entered?'));

  }




}

html代码

    <div *ngIf="!auth.currentUser; else alreadyLoggedIn">

  <h3>Social Login</h3>


    <button (click)="signInWithGoogle()" class="button btn-social btn-google">
      <i class="fa fa-google-plus fa-lg"></i> Connect Google
    </button>

    <button (click)="signInWithGithub()" class="button btn-social btn-github">
      <i class="fa fa-github fa-lg"></i> Connect GitHub
    </button>

    <button (click)="signInWithFacebook()" class="button  btn-social btn-facebook">
      <i class="fa fa-facebook fa-lg"></i> Connect Facebook
    </button>

    <button (click)="signInWithTwitter()" class="button  btn-social btn-twitter">
      <i class="fa fa-twitter fa-lg"></i> Connect Twitter
    </button>

    <hr>

    <h3>Anonymous Login</h3>

      <button (click)="signInAnonymously()" class="button button-info">
        <i class="fa fa-user-secret fa-lg"></i> Connect Anonymously
      </button>

    <hr>


  <h1>Sign In with Your Phone Number</h1>


  <label for="phone">Phone Number</label><br>

  <input type="text" [(ngModel)]="phoneNumber.country"  class="input" placeholder="1"    maxlength="2">

  <input type="text" [(ngModel)]="phoneNumber.area"     class="input" placeholder="949"  maxlength="3">

  <input type="text" [(ngModel)]="phoneNumber.prefix"   class="input" placeholder="555"  maxlength="4">



  <div id="recaptcha-container"></div>


  <button (click)="sendLoginCode()">SMS Text Login Code</button>


  <div *ngIf="windowRef.confirmationResult">

    <hr>

    <label for="code">Enter your Verification Code Here</label><br>

    <input type="text" name="code" [(ngModel)]="verificationCode">


    <button (click)="verifyLoginCode()">Verify</button>

  </div>


</div>




<ng-template #alreadyLoggedIn>
  <p class="text-success">
    Already logged in!
  </p>
</ng-template>

AUTH-服务

import { Injectable } from '@angular/core';
import { AngularFireDatabaseModule, AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import { Router } from "@angular/router";
import * as firebase from 'firebase';


@Injectable()
export class AuthService {

  authState: any = null;

  constructor(private afAuth: AngularFireAuth,
              private db: AngularFireDatabase,
              private router:Router) {

            this.afAuth.authState.subscribe((auth) => {
              this.authState = auth
            });
          }

  // Returns true if user is logged in
  get authenticated(): boolean {
    return this.authState !== null;
  }

  // Returns current user data
  get currentUser(): any {
    return this.authenticated ? this.authState : null;
  }

  // Returns
  get currentUserObservable(): any {
    return this.afAuth.authState
  }

  // Returns current user UID
  get currentUserId(): string {
    return this.authenticated ? this.authState.uid : '';
  }


  get windowRef(){
    return window
  }




}

enter image description here

I don't see the repatcha container

4 个答案:

答案 0 :(得分:1)

我的项目中有同样的问题。我想分享我的解决方案。我希望这会对某人有所帮助。

我意识到我们应该在app.component.ts中使用recaptcha-container。因为我们应该在用户登录站点时每次运行此验证码时运行。用户登录时,我正在使用它。 首先,我为窗口变量创建一个服务。

import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class WindowService {
 windowRef: any = window;
 constructor() { }
}

然后,我在app.component.ts中为Recaptcha创建一个实例。

  recaptchaVerifier() {
   this.windowService.windowRef.recaptchaVerifier = new 
    firebase.auth.RecaptchaVerifier(
     "recaptcha-container",
     {
      size: "invisible"
     }
   );
  }
  ngOnInit(){
    this.recaptchaVerifier();
  }

app.component.html

<div id="recaptcha-container"></div>

然后,当我使用该实例时。

loginByPhone(phone, this.windowService.windowRef.recaptchaVerifier);

您可以将confirmationResult设置为正在使用的此变量(windowRef)。 最后,您必须重新设置验证码,何时可以再次使用。您可以在此链接中找到-> https://stackoverflow.com/a/45807140/9207947

答案 1 :(得分:0)

这是您可靠的来源! https://developers.google.com/recaptcha/docs/invisible

看起来像div <div id="recaptcha-container"></div>尚未添加到您的DOM中,而是在您的类构造函数中。

Angular 2也不希望您直接更改DOM。您应该使用ElementRef或ViewChild更改DOM!祝你好运!

更新:以下是将其添加到dom的方法。运行命令

iElement.html('<div id="recaptcha-container"></div>');

in angular2。

该命令将该元素添加到dom!

更新#2 :尝试添加以下内容:

首先通过

从npm安装recaptcha
npm install angular2-recaptcha

将以下内容添加到SystemJS配置中:

System.config({
    map: {
        'angular2-recaptcha': 'node_modules/angular2-recaptcha'
    },
    packages: {
        app: {
            format: 'register',
            defaultExtension: 'js'
        },
        'angular2-recaptcha': {defaultExtension: 'js', main:'index'}
    }
});

然后添加此模块:

...
import { ReCaptchaModule } from 'angular2-recaptcha';
...


...
@NgModule({
  imports: [...,ReCaptchaModule]
  })
...

然后将此添加到您的html:

 <re-captcha site_key="<GOOGLE_RECAPTCHA_KEY>"></re-captcha>

将GOOGLE_RECAPTCHA_KEY替换为您的Google reCaptcha公钥

答案 2 :(得分:0)

尝试搜索您的HTML

<script type="text/javascript" src="angular-recaptcha.js"></script>

 <script src="https://www.google.com/recaptcha/api.js" async defer></script>


  <div class="g-recaptcha" data-sitekey="your_site_key"></div>

答案 3 :(得分:0)

这可能很晚了,仍然把它放在这里为任何人带来好处。 我遇到了同样的问题,下面的步骤解决了这个问题:

已替换:

<div *ngIf="showRecaptchaDiv">

收件人:

<div [hidden]="!showRecaptchaDiv">

  

*ngIf更改为[hidden]对我有用。