Reputation: 1046
I was wondering how can i initialise firebase app check using angular.
I am using angular fire but I am not sure how to initalise firebase app check before using any of the services
the docs have this
Add the following initialization code to your application, before you access any Firebase services.
firebase.initializeApp({ // Your firebase configuration object }); const appCheck = firebase.appCheck(); // Pass your reCAPTCHA v3 site key (public key) to activate(). Make sure this // key is the counterpart to the secret key you set in the Firebase console. appCheck.activate('abcdefghijklmnopqrstuvwxy-1234567890abcd');
But how can this be done in app module. Currently i import angular fire like so
@NgModule({
declarations: [
...
],
imports: [
AngularFireModule.initializeApp(environment.firebaseConfig),
],
]
Update:
I know this is probably not yet part of the angular fire library due to how new firebase app-check is but I have noticed there is a native firebase library https://www.npmjs.com/package/@firebase/app-check
I am happy for this to be used (e.g. somehow overriding the native firebase js object) as long as the code is able to apply it in the correct location before any services are called and that it gives no compilation errors in typescript
For reference my versions are as follows:
Angular: 10.2.5
Firebase: 8.6.0
AngularFire: 6.1.5
The debug localhost version must also work
Upvotes: 5
Views: 5254
Reputation: 10623
You could also achieve this with a service and interceptor (code below). The service should probably add some kind of caching of tokens (shorter TTLs for more security, longer TTLs for lower costs). See Enable App Check with reCAPTCHA Enterprise in web apps for more detail.
To keep the service implementation simple, the token caching code is not included.
The service holds the logic to get a token using App Check.
import { Injectable } from '@angular/core';
import { FirebaseApp, initializeApp } from 'firebase/app';
import { AppCheck, AppCheckTokenResult, getToken, initializeAppCheck, ReCaptchaEnterpriseProvider } from 'firebase/app-check';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
})
export class AppCheckService {
app: FirebaseApp;
appCheck: AppCheck;
constructor() {
this.app = initializeApp(environment.firebase);
// Create a ReCaptchaEnterpriseProvider instance using reCAPTCHA Enterprise.
this.appCheck = initializeAppCheck(this.app, {
provider: new ReCaptchaEnterpriseProvider(environment.recaptchaEnterpriseKey),
isTokenAutoRefreshEnabled: true // Set to true to allow auto-refresh.
});
}
async getToken(): Promise<AppCheckTokenResult | undefined> {
let appCheckTokenResponse;
try {
appCheckTokenResponse = await getToken(this.appCheck);
} catch (err) {
// TODO: Handle any errors if the token was not retrieved.
return;
}
return appCheckTokenResponse;
}
}
This service can then be used by an interceptor which is responsible for adding a X-Firebase-AppCheck
HTTP header with the token.
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AppCheckTokenResult } from '@firebase/app-check';
import { from, Observable } from 'rxjs';
import { switchMap, take } from 'rxjs/operators';
import { environment } from '../../environments/environment';
import { AppCheckService } from '../services/app-check.service';
@Injectable()
export class AppCheckInterceptor implements HttpInterceptor {
constructor(private readonly appCheckService: AppCheckService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.appCheckService.getToken()).pipe(
take(1), // See https://stackoverflow.com/a/60196923/828547.
switchMap((token: AppCheckTokenResult | undefined) => {
if (token) {
request = request.clone({
setHeaders: { "X-Firebase-AppCheck": token?.token },
});
}
return next.handle(request);
}),
);
}
}
You will need to add recaptchaEnterpriseKey
to your Angular environment files
export const environment = {
recaptchaEnterpriseKey: '6LfGni324khkjh324hkDSFsdfSfsdm',
};
And finally add the interceptor to your app.module.ts
file
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AppCheckInterceptor,
multi: true,
},
]
Upvotes: 5
Reputation: 1053
Do this:
// firebase-initialization.ts
import firebase from 'firebase/app';
import 'firebase/app-check';
// Environment Config
import { environment } from './path/to/environments';
const app = firebase.initializeApp(environment.firebase);
const appCheck = app.appCheck()
appCheck.activate('');
Then import the file in the app module as:
import "firebase-initialization"
Upvotes: 8
Reputation: 602
I had to use the event DOMContentLoaded to make app check work with my angularJS app, maybe you can try it:
window.addEventListener('DOMContentLoaded', () => {
var appCheck = firebase.appCheck()
appCheck.activate('captchatokenid')
})
Upvotes: 1