gpt4 book ai didi

angular - APP_INITIALIZER 和依赖 token 解析问题

转载 作者:行者123 更新时间:2023-12-03 16:38:38 26 4
gpt4 key购买 nike

我正在使用 APP_INITIALIZER 从 json 获取配置,它工作正常。
早些时候我有一个身份验证作为应用程序的一部分,它曾经工作得很好。

然后我们将授权逻辑拆分到一个库中,如果我们调用 forRoot() 或者如果我们为 config 提供静态值但允许动态配置,我使用库中的 InjectionToken 来提供配置而不调用 forRoot,它可以正常工作。

的代码app.module.ts 是这样的:

let authConfig: any;

export function authConfigFactory() {
return authConfig;
}

export function appInitializerFn(appConfigService: AppConfigService) {
return () => {
return appConfigService.loadAppConfig().then(() => {
authConfig = {
clientId: appConfigService.getConfig().CLIENT_ID,
tokenEndpoint: appConfigService.getConfig().TOKEN_URL,
redirectURL: "http://localhost",
};
});
};
};

@NgModule({
.....
imports: [
..
AuthLib
],
providers: [
AppConfigService,
{
provide: APP_INITIALIZER,
useFactory: appInitializerFn,
multi: true,
deps: [AppConfigService]
},
AuthLibService,
{
provide: 'authConfig',
useFactory: authConfigFactory,
deps: []
},
.....
]
bootstrap: [AppComponent]
})
export class AppModule { }

现在 authConfigFactory 在 appInitializerFn 之前被调用,导致未定义,如果我将异步添加到 authConfigFactory 以防止返回语句直到其定义,然后将空值馈送到 AuthGuard 导致无效的 token url。

如果我在调用 promise 之前在 appInitializerFn 中手动提供值,则值会被翻译并且一切正常。但在那个阶段,动态值不存在。

的代码应用配置.service.ts :
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { AppConfig } from '../_models/app-config';
import { LoggingService } from './logging.service';

@Injectable()
export class AppConfigService {
static appConfig : AppConfig;
private dataLoc: string;
constructor(private http: HttpClient,
private logger: LoggingService) { }

loadAppConfig() {
if(environment.production){
this.dataLoc = '/assets/data/appConfig.json';
}
else{
this.dataLoc = '/assets/data/appConfig-dev.json';
}
return new Promise<void>((resolve, reject) => {
this.http.get(this.dataLoc).toPromise().then((response: AppConfig) => {
AppConfigService.appConfig = <AppConfig>response;
resolve();
}).catch((response: any) => {
reject(`Could not load file '${this.dataLoc}':
${JSON.stringify(response)}`);
});
});
}
getConfig() {
return AppConfigService.appConfig;
}
}

库或代码中缺少任何东西来使这项工作?

我对 Angular 制度有点陌生,即使我犯了一些愚蠢的错误,也请告诉我。

最佳答案

于是找到了原因和解决办法。为任何人发布它都会绊倒这个问题。

由于 APP_INITIALIZER 被正确调用。我错过的事情是我正在使用“HttpClient”来获取配置,而该配置又会调用 ROOT 中定义的任何 HTTP_INTERCEPTORS 并最终导致身份验证服务的初始化,而身份验证服务又需要身份验证配置作为构造函数中的 token 注入(inject)。

因此, token 甚至在获取值之前就被注入(inject),导致它变为未定义/空。

解决方案虽然很简单,但我们可以使用

  • HttpBackend 获取 json 或
  • 获取 main.ts 或
  • 中的 json
  • 防止为该 json 路径调用拦截器。

  • 在我的情况下,第 3 点是不可能的,因为我想严格控制所有通信,而第 2 点有点笨拙。我们采用了方法 1。共享修改后的代码以供引用。
    import { Injectable } from '@angular/core';
    import { HttpClient, HttpBackend } from '@angular/common/http';
    import { environment } from 'src/environments/environment';
    import { AppConfig } from '../_models/app-config';
    import { LoggingService } from './logging.service';

    @Injectable()
    export class AppConfigService {
    static appConfig : AppConfig;
    private dataLoc: string;
    constructor(private handler: HttpBackend,
    private logger: LoggingService) { }

    loadAppConfig() {
    if(environment.production){
    this.dataLoc = '/assets/data/appConfig.json';
    }
    else{
    this.dataLoc = '/assets/data/appConfig-dev.json';
    }
    return new HttpClient(this.handler).get(this.dataLoc)
    .toPromise()
    .then((data:AppConfig) => {
    this.logger.info(data);
    AppConfigService.appConfig = data;
    });
    }
    getConfig() {
    return AppConfigService.appConfig;
    }
    }

    感谢@ysf,您的最小示例给了我这样的想法,即如果它在一般情况下工作,那么在初始化期间还有其他东西正在调用 authconfig。

    关于angular - APP_INITIALIZER 和依赖 token 解析问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56928730/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com