For an updated answer, see Correct way to integrate reCAPTCHA with Angular 4
.Original answer
For Typescript, declare grecaptcha:
declare var grecaptcha: any;
This assumes that the reCAPTCHA API has been enabled ,
<script src='https://www.google.com/recaptcha/api.js?render=explicit'></script>
Alternatively, grecaptchayou can type as follows:
declare var grecaptcha: ReCAPTCHA;
ReCAPTCHA Interface
import { ElementRef } from '@angular/core';
export interface ReCAPTCHA {
execute(opt_widget_id?: string): void;
render(container: ElementRef|string, parameters: {[key: string]: string}): void;
reset(opt_widget_id?: string): void;
getResponse(opt_widget_id?: string): string;
}
ExampleExample
The following code is an outline and does not show a ReCAPTCHA check on the server side.
ReCAPTCHA Service
import { Injectable, OnInit } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs';
export interface ReCAPTCHAResponse {
success: boolean;
status_code: number,
error_codes?: Array<string>;
}
@Injectable()
export class ReCAPTCHAService {
public recaptchaResponse$: Observable<ReCAPTCHAResponse>;
public constructor(private http: Http) {}
public verifyUserResponse(userResponseToken: string): Observable<ReCAPTCHAResponse> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post('/auth/captcha', {'g-recaptcha-response': userResponseToken}, options)
.map( (res: Response) => this.extractData(res))
.catch( (error: Response | any) => this.handleError(error));
}
private extractData(res: Response): ReCAPTCHAResponse {
const recaptchaResponse: ReCAPTCHAResponse = res.json();
return recaptchaResponse;
}
private handleError (error: Response | any): Observable<ReCAPTCHAResponse> {
let errMsg: string;
if (error instanceof Response) {
let body = error.json() || '';
let err = body.error || JSON.stringify(body);
errMsg = error.status + ' - ' + (error.statusText || '') + ': ' + err;
} else {
errMsg = error.message ? error.message : error.toString();
}
return Observable.throw({ success: false, status_code: 0, error_codes: [errMsg]});
}
}
component
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ReCAPTCHA } from './recaptcha';
import { ReCAPTCHAResponse, ReCAPTCHAService } from './recaptcha.service';
declare var grecaptcha: ReCAPTCHA;
declare var window: any;
@Component ({
moduleId: module.id,
selector: 'create-account',
templateUrl: 'create-account.component.html'
})
export class CreateAccountComponent implements OnDestroy, OnInit {
public constructor(private recaptcha: ReCAPTCHAService, private formBuilder: FormBuilder) {}
public ngOnInit(): void {
this.buildForms();
window['reCAPTCHACallback'] = this.reCAPTCHACallback.bind(this);
grecaptcha.render('create-account-captcha', {
'sitekey': 'your-site-key',
'size': 'invisible',
'callback': 'reCAPTCHACallback'
});
}
public reCAPTCHACallback(token: string) {
if (token == null || token.length === 0) {
grecaptcha.reset();
} else {
let response$: Observable<ReCAPTCHAResponse>;
response$ = this.recaptcha.verifyUserResponse(token);
response$.subscribe( r => {
if (r.success) {
} else {
grecaptcha.reset();
}
},
(error: any) => {
});
}
}
private buildForms(): void {
}
}