Search code examples
angularswagger-codegenoidc-client-js

Configuring OAuth2 access token to typescript-angular2 client


I do not fully understand how to provide OAuth2 access token from a promise (oidc-client-js) to API code generated with Swagger-CodeGen.

It is easy to provide constant values, but how do I change below to get the user's access token from oidc-client-js? I would like to know the "correct" way. It would be easy enough to stick this token somewhere in a global variable.

@NgModule({
  imports: [
    CommonModule,
    ApiModule.forConfig(() => new Configuration({
      accessToken: 'my-access-token' //this can also be a () => string function
    }))
  ],

In normal components with OnInit, I can get the token in a promise from an instance of oidc-client's UserManager. Making these two pieces fit together is what confuses me. One seems like static configuration and the other needs to subscribe to a singleton's promise.

this.userSubscription = this.authService.getUser().subscribe((user) => {
    if (user) {
        this.access_token = user.access_token;
    }
});

Any corrections to things I am doing wrong would also be appreciated. This is my first prototype using Angular.


Update

After applying Ben's suggestion and taking time to understand APP_INITIALIZER (which is marked experimental and very sparsely documented imo), it felt like overkill. I ended with the following custom provider for the Configuration class which gets injected into TypeScript-Angular2 service code generated with Swagger-CodeGen:

providers: [
  AuthService,
  AuthGuardService,
  {
    provide: Configuration,
    useFactory: (authSvc: AuthService) => new Configuration({accessToken: authSvc.getAccessToken.bind(authSvc)}),
    deps: [AuthService],
    multi: false
  }
]

I changed my AuthService to store the user's latest access_token on the service. The getAccessToken() method is called from the Swagger-CodeGen generated code and returns the latest jwt for use in HTTP headers. It feels clean and it works. Please let me know if (and why) this is the wrong way to solve my problem.


Solution

  • You need to use the APP_INITIALIZER to bootstrap your API token, take a look at my answer Pass web application context to Angular2 Service to see an example of how to do that.