将OAuth2访问令牌配置到typescript-angular2客户端
我不完全理解如何将OAuth2访问令牌从promise(oidc客户端js)提供给使用Swagger CodeGen生成的API代码 提供常量值很容易,但如何在下面进行更改以从oidc客户端js获取用户的访问令牌?我想知道“正确”的方法。将此标记粘贴到全局变量中的某个位置是很容易的将OAuth2访问令牌配置到typescript-angular2客户端,angular,swagger-codegen,oidc-client-js,Angular,Swagger Codegen,Oidc Client Js,我不完全理解如何将OAuth2访问令牌从promise(oidc客户端js)提供给使用Swagger CodeGen生成的API代码 提供常量值很容易,但如何在下面进行更改以从oidc客户端js获取用户的访问令牌?我想知道“正确”的方法。将此标记粘贴到全局变量中的某个位置是很容易的 @NgModule({ imports: [ CommonModule, ApiModule.forConfig(() => new Configuration({ access
@NgModule({
imports: [
CommonModule,
ApiModule.forConfig(() => new Configuration({
accessToken: 'my-access-token' //this can also be a () => string function
}))
],
在使用OnInit的普通组件中,我可以从oidc客户机的UserManager实例获得承诺中的令牌。让这两件东西结合在一起让我很困惑。一个看起来像是静态配置,另一个需要订阅singleton的承诺
this.userSubscription = this.authService.getUser().subscribe((user) => {
if (user) {
this.access_token = user.access_token;
}
});
对我所做错事的任何纠正也将不胜感激。这是我第一个使用Angular的原型
更新 在应用了本的建议并花时间去理解APP_初始值设定项(在国际海事组织,它被标记为实验性的,并且很少有文献记载)之后,感觉有点过头了。我以配置类的以下自定义提供程序结束,该类被注入到使用Swagger CodeGen生成的TypeScript-Angular2服务代码中:
providers: [
AuthService,
AuthGuardService,
{
provide: Configuration,
useFactory: (authSvc: AuthService) => new Configuration({accessToken: authSvc.getAccessToken.bind(authSvc)}),
deps: [AuthService],
multi: false
}
]
我更改了AuthService以在服务上存储用户的最新访问令牌。从Swagger CodeGen生成的代码调用
getAccessToken()
方法,并返回最新的jwt以在HTTP头中使用。它摸起来很干净,而且很有效。请让我知道这是否(以及为什么)是解决我问题的错误方法。你需要使用APP\u初始值设定项来引导你的API令牌,看看我的答案,看看如何做到这一点。我认为这是一个招摇过市的代码错误,属性签名应该是
accessToken?: string | (() => Promise<string>);
我不喜欢这个解决方案的地方是它会截获所有HTTPClient调用,这就是为什么我必须添加if(req.url.startsWith(environment.usersAPIBasePath).
但如果所有HTTPClient调用都是对API的调用,那么可以删除该部分条件语句
这就是该应用程序的提供者在app.module.ts
中的工作方式:
providers: [
...
{ provide: BASE_PATH, useValue: environment.usersAPIBasePath },
{ provide: HTTP_INTERCEPTORS, useClass: UsersApiAuthInterceptorService, multi: true },
],
你们有工作样品吗?
import { Injectable } from '@angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { AngularFireAuth } from '@angular/fire/auth';
import * as firebase from 'firebase/app';
import { from } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
import { environment } from '../environments/environment';
@Injectable({
providedIn: 'root'
})
export class UsersApiAuthInterceptorService implements HttpInterceptor {
constructor(private afAuth: AngularFireAuth) { }
intercept(req: HttpRequest<any>, next: HttpHandler) {
if (req.url.startsWith(environment.usersAPIBasePath) && this.afAuth.auth.currentUser) {
return from(this.afAuth.auth.currentUser.getIdToken()).pipe(mergeMap(token => {
console.log('UsersApiAuthInterceptorService got token', token);
const authReq = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(authReq);
}));
}
else {
return next.handle(req);
}
}
}
providers: [
...
{ provide: BASE_PATH, useValue: environment.usersAPIBasePath },
{ provide: HTTP_INTERCEPTORS, useClass: UsersApiAuthInterceptorService, multi: true },
],