2

So... I'm migrating my "old" code that was using the HttpModule and angular2-jwt lib.

Before, I could make angular2-jwt work with the following config:

export function authHttpServiceFactory(
  http: Http, options: RequestOptions, myService: MyService) {

  return new AuthHttp(new AuthConfig({
    globalHeaders: [{'Content-Type': 'application/json'}],
    noJwtError: true,
    tokenGetter: (() => myService.get('my_token'))
  }), http, options);
}

@NgModule({
  providers: [
    {
      provide: AuthHttp,
      useFactory: authHttpServiceFactory,
      deps: [Http, RequestOptions, MyService]
    }
  ]
})
export class AuthModule {}

... But now, to use it with the new HttpClientModule I have to use the new version of angular2-jwt (@auth-angular-jwt - I know it's still in beta version) and I'm trying to figure out that I need to do to access my service to get the token (as I used to do).

My actual config is (same as git's example):

@NgModule({
  // ...
  imports: [
    HttpClientModule,
    JwtModule.forRoot({
      config: {
        tokenGetter: () => {
          return <myService>.getToken(); // Here
        }
      }
    })
  ]
})
export class AppModule {}

Is it possible? Thanks in advance.

dev_054
  • 3,448
  • 8
  • 29
  • 56

1 Answers1

4

This can be done by overriding config service:

export const jwtOptionsFactory = (dependency) => ({
    tokenGetter: () => dependency.getToken(),
    whitelistedDomains: []
});

...
imports: [
    JwtModule.forRoot({
        config: { tokenGetter(): string { throw new Error('no tokenGetter') } }
    })
],
providers: [{
    provide: JWT_OPTIONS,
    deps: [Dependency],
    useFactory: jwtOptionsFactory
}]

Starting from 1.0.0-beta.8, forRoot accepts options provider:

...
imports: [
    JwtModule.forRoot({
        jwtOptionsProvider: {
            provide: JWT_OPTIONS,
            deps: [Dependency],
            useFactory: jwtOptionsFactory
        }
    })
]
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Thanks for your answer, unfortunately it doesn't work (at least for me)... it throws the following error: `Cannot read property 'split' of null`. It seems like the `tokenGetter` is null even setting it in `useFactory`. – dev_054 Jul 31 '17 at 02:15
  • The very same solution works for me as expected. Provider overriding is quite straightforward in Angular, it may not work if you provide JWT_OPTIONS and import JwtModule in different modules (race condition). Make sure you don't have compilation errors and use last package version (1.0.0-beta.6). You can try to reassemble the module in `providers` [like that](https://github.com/auth0/angular2-jwt/blob/v1.0/index.ts#L33-L44) instead of importing JwtModule, but the result should be same as above. – Estus Flask Jul 31 '17 at 02:31
  • I'm doing everything in `app.module` and no I don't have any compilation errors and the version is latest (1.0.0-beta.6). – dev_054 Jul 31 '17 at 02:48
  • From what I see [here](https://github.com/auth0/angular2-jwt/blob/v1.0/src/jwthelper.service.ts#L80), null seems to be returned from your function and doesn't result from bogus tokenGetter. I updated the post to address this ambiguity. – Estus Flask Jul 31 '17 at 02:54
  • Starting from 1.0.0-beta.8, forRoot accepts options provider. – Estus Flask Aug 01 '17 at 09:15
  • Thanks, it works. Currently, I'm doing it by myself, because using `@auth/angular-jwt` it's impossible (1.0.0-beta.9) to send unauthenticated request (to get the initial token before send other requests). – dev_054 Aug 05 '17 at 01:35
  • @dev_054 "it's impossible (1.0.0-beta.9) to send unauthenticated request (to get the initial token before send other requests)" That's not true, at least with latest version. Simply pass an empty token in the authorization header. –  Apr 13 '18 at 11:54