【问题标题】:How to initialise Firebase App Check in Angular如何在 Angular 中初始化 Firebase 应用检查
【发布时间】:2021-08-26 17:38:42
【问题描述】:

我想知道如何使用 Angular 初始化 Firebase 应用检查。

我正在使用 angular fire,但我不确定如何在使用任何服务之前初始化 firebase 应用程序检查

文档有这个

在您访问任何 Firebase 服务之前,将以下初始化代码添加到您的应用程序中。

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');

但是如何在 app 模块中做到这一点。目前我像这样导入角火

@NgModule({
  declarations: [
   ...
  ],
  imports: [
    AngularFireModule.initializeApp(environment.firebaseConfig),
  ],
]

更新:

我知道这可能还不是 angular fire 库的一部分,因为新的 firebase app-check 是多么的新,但我注意到有一个本地 firebase 库 https://www.npmjs.com/package/@firebase/app-check

我很高兴使用它(例如,以某种方式覆盖本机 firebase js 对象),只要代码能够在调用任何服务之前将它应用到正确的位置并且它不会在 typescript 中产生编译错误

作为参考,我的版本如下:

角度: 10.2.5

火力基地: 8.6.0

角火: 6.1.5

调试本地主机版本也必须工作

【问题讨论】:

    标签: angular typescript firebase firebase-app-check


    【解决方案1】:

    这样做:

    // 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('');
    

    然后将app模块中的文件导入为:

    import "firebase-initialization"
    

    【讨论】:

    • 我已经尝试过这个解决方案,但是在我这样做之后我得到:@firebase/app-check: FirebaseError: AppCheck: Fetch server 返回了 HTTP 错误状态。 HTTP 状态:403。(appCheck/fetch-status-error)。此外,当调用云函数时,我得到:未捕获(承诺):错误:未验证,尽管我没有添加任何代码来在我的云函数中强制执行它。我的网络应用程序过去可以正常工作。我在 firebase 控制台中启用了 App Check。是否导入:AngularFireModule.initializeApp(environment.firebase) 仍需要在应用模块中?
    • 是的,它应该还在应用模块中,因为它会配置其他东西。
    • 我试过这个,但我马上就收到一个错误:./src/app/app.module.ts 中的错误模块未找到:错误:无法解析“firebase 初始化”在 'my-angular-project-path\src\app' 不确定发生了什么,但我已将其命名为 firebase-initialization.ts,它位于 src/app 文件夹中,与我的 app.module.ts 文件相同。
    【解决方案2】:

    我不得不使用事件 DOMContentLoaded 来使应用检查与我的 angularJS 应用一起工作,也许你可以尝试一下:

    window.addEventListener('DOMContentLoaded', () => {
      var appCheck = firebase.appCheck()
      appCheck.activate('captchatokenid')
    })
    

    【讨论】:

      【解决方案3】:

      您也可以使用服务和拦截器来实现这一点(代码如下)。该服务可能应该添加某种类型的令牌缓存(更短的 TTL 以提高安全性,更长的 TTL 以降低成本)。详情请参阅Enable App Check with reCAPTCHA Enterprise in web apps

      为保持服务实现简单,不包括令牌缓存代码。

      服务持有使用 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;
        }
      }
      
      

      然后,该服务可以被拦截器使用,该拦截器负责添加带有令牌的X-Firebase-AppCheck HTTP 标头。

      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);
                  }),
              );
          }
      }
      

      您需要将 recaptchaEnterpriseKey 添加到您的 Angular 环境文件中

      export const environment = {
        recaptchaEnterpriseKey: '6LfGni324khkjh324hkDSFsdfSfsdm',
      };
      

      最后将拦截器添加到您的app.module.ts 文件中

      providers: [
       {
            provide: HTTP_INTERCEPTORS,
            useClass: AppCheckInterceptor,
            multi: true,
       },
      ]
      

      【讨论】:

        猜你喜欢
        • 2016-10-05
        • 1970-01-01
        • 1970-01-01
        • 2020-02-03
        • 2013-11-10
        • 2017-10-15
        • 1970-01-01
        • 1970-01-01
        • 2021-04-04
        相关资源
        最近更新 更多