[英]APP_INITIALIZER not awaiting (Angular 13)
我正在從 okta/okta-angular 3.x 更新到 5.x。 它似乎引入了一個奇怪的錯誤。
當應用程序第一次啟動時,我們一直在使用 APP_INITIALIZER 執行appInitializerFactory(configService: ConfigService)
,它會調用 http 來加載配置數據。
調用如下所示:
public async loadConfig(): Promise<any> {
return this.httpClient.get('assets/config.json').pipe(settings => settings)
.toPromise()
.then(settings => {
this.config = settings as IAppConfig;
})
.catch(exception => {
console.log("Exception encountered while retreiving configuration");
});
}
在更新到 okta 5.x 之前,APP_INITIALIZER 一直在等待 promise。 現在,在 APP_INITILIZER 中的 promise 完成之前,似乎正在解決其他提供程序。
產生的問題發生在oktaInitializerFactory
的下游,它運行以下代碼:
public oktaConfig() {
return Object.assign({
onAuthRequired: (oktaAuth: OktaAuth, injector: Injector) => {
const router = injector.get(Router);
router.navigate(['/login']);
}
}, this.config.oktaConfig);
}
在最后一行, this.config.oktaConfig
以undefined
的形式返回,因為 APP_INITIALIZER 尚未完成等待。
這是完整的 app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { Routes, RouterModule, Router } from '@angular/router';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { MaterialModule } from './modules/material/material.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TablesComponent } from './components/tables/tables.component';
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { ToolbarComponent } from './components/toolbar/toolbar.component';
import { LoginComponent } from './components/login/login.component';
import { FormsModule } from '@angular/forms';
import { RunLogComponent } from './components/run-log/run-log.component';
import { RunDataComponent } from './components/run-data/run-data.component';
import { ActionComponent } from './components/action/action.component';
import { ErrorsComponent } from './components/errors/errors.component';
import { OktaAuth } from '@okta/okta-auth-js';
import { OKTA_CONFIG, OktaAuthGuard, OktaAuthModule, OktaCallbackComponent } from '@okta/okta-angular';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { TabulatorUserTableComponent } from './components/tabulator-user-table/tabulator-user-table.component';
import { TabulatorTableComponent } from './components/tabulator-table/tabulator-table.component';
import { DataLakeComponent } from './components/data-lake/data-lake.component';
import { IntegrationHistoryComponent } from './components/integration-history/integration-history.component';
import { IntegrationStatusComponent } from './components/integration-status/integration-status.component';
import { MatSpinnerButtonComponent } from './components/mat-spinner-button/mat-spinner-button.component';
import { ConfigService } from './services/config.service';
import { DataStudioComponent } from './components/data-studio/data-studio.component';
import { IntegrationDashboardComponent } from './components/integration-dashboard/integration-dashboard.component';
import { IntegrationSelectorToolbarComponent } from './integration-selector-toolbar/integration-selector-toolbar.component';
import { PrimaryButtonsComponent } from './components/primary-buttons/primary-buttons.component';
import { UserCardComponent } from './components/user-card/user-card.component';
import { HttpOktaInterceptorService } from './services/http-okta-interceptor.service';
import { DebugInfoComponent } from './components/debug-info/debug-info.component';
import { ModalModule } from './modal';
import { DragNDrop } from './components/dropbox/drag-n-drop';
import { ProgressComponent } from './components/dropbox/progress/progress.component';
const appRoutes: Routes = [
{
path: '',
component: DashboardComponent,
canActivate: [OktaAuthGuard]
},
{
path: 'login/callback',
component: OktaCallbackComponent
},
{
path: 'login',
component: LoginComponent
}
];
@NgModule({
declarations: [
AppComponent,
TablesComponent,
PageNotFoundComponent,
DashboardComponent,
ToolbarComponent,
LoginComponent,
RunLogComponent,
RunDataComponent,
ActionComponent,
ErrorsComponent,
TabulatorUserTableComponent,
TabulatorTableComponent,
DataLakeComponent,
IntegrationHistoryComponent,
IntegrationStatusComponent,
MatSpinnerButtonComponent,
DataStudioComponent,
IntegrationDashboardComponent,
IntegrationSelectorToolbarComponent,
PrimaryButtonsComponent,
UserCardComponent,
DebugInfoComponent,
ProgressComponent,
DragNDrop
],
imports: [
BrowserModule,
OktaAuthModule,
RouterModule.forRoot(appRoutes, { relativeLinkResolution: 'legacy' }),
BrowserAnimationsModule,
MaterialModule,
FormsModule,
HttpClientModule,
ModalModule
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: appInitializerFactory,
deps:[ConfigService],
multi: true
},
{
provide: OKTA_CONFIG,
useFactory: oktaInitializerFactory,
deps:[ConfigService],
},
{
provide: HTTP_INTERCEPTORS,
useClass: HttpOktaInterceptorService,
multi: true,
deps: [OktaAuth]
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function appInitializerFactory(configService: ConfigService) {
return () => configService.loadConfig();
}
export function oktaInitializerFactory(configService: ConfigService) {
return configService.oktaConfig();
}
我的 APP_INITIALIZER 在其他代碼執行之前沒有完成是否有特殊原因? 當我降級回 okta 3.x 時,這個問題就消失了。
事實證明,從Okta 3
升級到4+
或5+
確實引入了一個變化,這使得在APP_INITIALIZER
中加載身份驗證服務器配置成為一個不可行的選項。
簡而言之,okta-angular 將在APP_INITIALIZER
完成之前嘗試連接到身份驗證服務器。 解決方法是將配置數據加載到 main.ts 中的注入器中,該注入器在main.ts
之前APP_INITIALIZER
。 這在技術上違背了angular.io中的文檔,但Okta 支持已經驗證了這種行為[ 來源]
另一個用戶對 Auth0 做了類似的實現,遇到了同樣的問題,鏈接在這里: stackoverflow.com/a/66957293/3202440
我不知道它在以前的版本中應該如何工作。 你有依賴於ConfigService
的appInitializerFactory
。 ConfigService
依賴於HttpClient
。 HttpClient
=> HTTP_INTERCEPTORS
即在HttpOktaInterceptorService
上。 HttpOktaInterceptorService
=> OktaAuth
這很可能依賴於OKTA_CONFIG
。
這意味着要構造一個HttpClient
(它隱式地要求初始化器),您需要已經構造了OKTA_CONFIG
。 聽起來很合乎邏輯的是,這個配置初始化程序比APP_INITIALIZER
更早地被調用。
這種依賴很可能是在重構期間引入的,而不僅僅是更新。
在您的位置,我會嘗試消除對ConfigService
中HttpClient
的依賴,並使用本機 api 發出此請求
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.