diff --git a/README.md b/README.md
index d316741..fb93edf 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,7 @@ A simple, configurable, easy-to-start component for handling reCAPTCHA.
* [Resizing](#example-resizing)
* [SystemJS configuration](#example-systemjs)
* [Loading from a different location](#example-different-url)
+ * [Specifying nonce for Content-Security-Policy](#example-csp-nonce)
## Installation
@@ -357,3 +358,20 @@ import { RECAPTCHA_BASE_URL } from 'ng-recaptcha';
],
}) export class MyModule { }
```
+
+### Specifying nonce for Content-Security-Policy
+
+Per [reCAPTCHA FAQ on CSP](https://developers.google.com/recaptcha/docs/faq#im-using-content-security-policy-csp-on-my-website-how-can-i-configure-it-to-work-with-recaptcha), the recommended approach for that is to supply nonce to the script tag. This is possible by providing the `RECAPTCHA_NONCE` token, for example:
+
+```javascript
+import { RECAPTCHA_NONCE } from 'ng-recaptcha';
+
+@NgModule({
+ providers: [
+ {
+ provide: RECAPTCHA_NONCE,
+ useValue: '',
+ },
+ ],
+}) export class MyModule { }
+```
diff --git a/index.ts b/index.ts
index 3fbe848..0e4df11 100644
--- a/index.ts
+++ b/index.ts
@@ -1,4 +1,9 @@
export { RecaptchaComponent } from './recaptcha/recaptcha.component';
-export { RecaptchaLoaderService, RECAPTCHA_LANGUAGE, RECAPTCHA_BASE_URL } from './recaptcha/recaptcha-loader.service';
+export {
+ RecaptchaLoaderService,
+ RECAPTCHA_LANGUAGE,
+ RECAPTCHA_BASE_URL,
+ RECAPTCHA_NONCE,
+} from './recaptcha/recaptcha-loader.service';
export { RecaptchaModule } from './recaptcha/recaptcha.module';
export { RECAPTCHA_SETTINGS, RecaptchaSettings } from './recaptcha/recaptcha-settings';
diff --git a/recaptcha/recaptcha-loader.service.ts b/recaptcha/recaptcha-loader.service.ts
index 73cb064..d793ad7 100644
--- a/recaptcha/recaptcha-loader.service.ts
+++ b/recaptcha/recaptcha-loader.service.ts
@@ -10,6 +10,7 @@ import { BehaviorSubject, Observable, of } from 'rxjs';
export const RECAPTCHA_LANGUAGE = new InjectionToken('recaptcha-language');
export const RECAPTCHA_BASE_URL = new InjectionToken('recaptcha-base-url');
+export const RECAPTCHA_NONCE = new InjectionToken('recaptcha-nonce-tag');
@Injectable()
export class RecaptchaLoaderService {
@@ -25,15 +26,19 @@ export class RecaptchaLoaderService {
private language: string;
/** @internal */
private baseUrl: string;
+ /** @internal */
+ private nonce: string;
constructor(
// tslint:disable-next-line:no-any
@Inject(PLATFORM_ID) private readonly platformId: any,
@Optional() @Inject(RECAPTCHA_LANGUAGE) language?: string,
@Optional() @Inject(RECAPTCHA_BASE_URL) baseUrl?: string,
+ @Optional() @Inject(RECAPTCHA_NONCE) nonce?: string,
) {
this.language = language;
this.baseUrl = baseUrl;
+ this.nonce = nonce;
this.init();
this.ready = isPlatformBrowser(this.platformId) ? RecaptchaLoaderService.ready.asObservable() : of();
}
@@ -53,6 +58,10 @@ export class RecaptchaLoaderService {
const langParam = this.language ? '&hl=' + this.language : '';
const baseUrl = this.baseUrl || 'https://www.google.com/recaptcha/api.js';
script.src = `${baseUrl}?render=explicit&onload=ng2recaptchaloaded${langParam}`;
+ if (this.nonce) {
+ // tslint:disable-next-line:no-any Remove "any" cast once we upgrade Angular to 7 and TypeScript along with it
+ (script as any).nonce = this.nonce;
+ }
script.async = true;
script.defer = true;
document.head.appendChild(script);