我正在 Angular 项目中使用 MSAL 库进行单点登录身份验证。
在我的 app.module.ts 文件中,我想从 API 响应动态传递 client_id 参数。 我创建了一个配置服务,在 API 响应中获取 client_id 。但是如何调用该配置服务并在 app.module.ts 文件中动态传递 client_id 呢?
auth: {
clientId: <dynamic value from API response>,
authority: <dynamic value from API response>,
redirectUri: '/',
},
您需要能够发起授权尝试的功能,并为代码的其他部分提供等待答案并在发生更改时收到通知的方法。
有四种常见方法可以实现此目的。
虽然可能,但 Promise 会返回一个响应,而不是可能返回零个或多个更新的流。所以我认为这是一种替代方案,但我不会讨论如何实现它,因为我不会。
如果您使用的是最新版本的 Angular 并且您团队的其他成员对信号感到满意,那么我会这样做。
正如昨天宣布的那样,它们已准备好投入生产。 https://blog.angular.io/signal-inputs-available-in-developer-preview-6a7ff1941823
我要解释的方式是(字面上)上周的最佳实践。
假设您有一个具有私有方法“getAuth”的服务,该服务将尝试获取现有/新的身份验证并返回 auth 对象的承诺或可观察值。
您还可以在您的服务中包含以下内容
private authPromiseSubject$: Subject<ObservableInput<Auth>> = new Subject();
readonly auth$: Observable<undefined|Readonly<Auth>> = authPromiseSubject$.pipe(
// if a new one is added while waiting for an old one to resolve, toss the old one
switchAll(),
shareReplay(1)
);
readonly clientId$ = this.auth$.pipe(
map(auth => auth.clientId),
distinctUntilChanged(),
shareReplay(1)
);
ngOnInit() {
this.reload();
}
// Example property
readonly isLoggedOff: Observable<boolean> = this auth$.pipe(
map(auth => !auth?.clientId), // or whatever code makes sense
distinctUntilChanged(),
shareReplay(1)
);
// Example method, plus called onInit for initial loading
reload() {
this.authPromiseSubject$.next(
this.getAuth()
);
}
// Example method
logout() {
console.log("Log out server code goes here");
console.log("Clearing local session storage, too");
this.authPromiseSubject$.next(
of(undefined)
);
}
有了这样的服务,所有使用它并需要客户端 ID 的东西都可以从
clientId$
可观察到的管道进行传输。如果您将其尽可能长时间地保留在可观察量中,并且不通过 Typescript 订阅,而是在模板中使用异步管道,那么您的组件可以具有极高的反应性且相当高效。
NgRx 是一个代码库,它采用了我刚刚给您的示例并对其进行了扩展。并非我认识的每个 Angular 开发人员都了解 NgRx,但我不知道有哪个 Angular 开发人员了解 NgRx 并且不后悔早点学习它,并且可能会认为this 方法是最佳实践。你想怎样就怎样吧。 🙂