Im not sure if the JwtHelperService can be used together with the Interceptor. I want to use it in another service I have the following issue.
Cannot instantiate cyclic dependency! JWT_OPTIONS ("[ERROR ->]"): in NgModule CoreModule
Settings
CoreModule
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useFactory: jwtOptionsFactory,
deps: [TokenHandler]
}
}),
TokenHandler (own class for jwt decode ...)
constructor(private cookieService: CookieService, private jwtHelper: JwtHelperService) { }
Issue is solved. It's not an issue with the lib
@elvirdolic how did you solve using the JwtHelperService directly in your own service? I'm using the 1.0 beta 9 of auth0/angular-jwt
Hi,
you can inject it in your component, service ... as long you import the module because it's provided in the module and you can use it.
Thank you, I think what I was doing wrong is importing JwtHelperService in my app.module, and adding it to the providers when I also import JwtModuleand add it as well. I was able to use it correctly after getting rid of the service in app.module
I have the same issue, but I still don't know how to resolve it.
I import the JwtModule with the forRoot() stuff in my main app.module like this:
JwtModule.forRoot(
{
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useFactory: jwtOptionsFactory,
deps: [AuthService]
}
}
)
The jwtOptionsFactory looks like this:
export function jwtOptionsFactory(tokenService: AuthService) {
return {
tokenGetter: () => {
return tokenService.getToken();
}
}
}
Both the JwtHelperService and the HttpClient get injected into the AuthService, because it implements the token refreshing logic, too.
The resulting error looks like this:
Uncaught Error: Provider parse errors:
Cannot instantiate cyclic dependency! InjectionToken_HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
Cannot instantiate cyclic dependency! InjectionToken_JWT_OPTIONS ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
The AuthService is placed inside its own AuthModule, which is also included (with forRoot()) in the appModule. The JwtModule is only included in the AppModule though.
Oh another maybe useful info: I'm using my own (second) interceptor to handle token refresh logic, which depends on the AuthService, too.
Is there something I did wrong?
@lehoffma I have the same problem, did you manage to solve it ?
Yeah, instead of using the jwtOptionsProvider property, I defined a tokenGetter function in the app.module.ts file, which does the same stuff as the function in the AuthService.
The function:
export function tokenGetter() {
return localStorage.getItem("auth_token");
}
Inside the @NgModule declaration:
...
JwtModule.forRoot(
{
config: {
tokenGetter: tokenGetter
}
}
),
...
Certainly not the prettiest or best solution, but it was good enough for me.
@fredrocheron, @lehoffma Guys, first you need to add it in your main app module (BTW you can use useClass prop to bypass Injectable class if you want):
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useClass: TokenFactory
}
})
Second step: if TokenFactory has a dependency on JwtHelperService or smth from @auth0/angular-jwt remove them from the constructor (Your circular dependency I believe, at least was mine :) ).
@Injectable()
export class TokenFactory {
public skipWhenExpired: boolean = true;
public whitelistedDomains: RegExp[] = [
// Your domains string[] or RegExp[]
];
// Remove all deps from @auth0/angular-jwt
constructor(@Inject(localStorage) protected localStorage: any) {}
public tokenGetter = () => this.localStorage.getItem('your_key');
}
Third: if you need to build another class that works with tokens, you can just make a derived from TokenFactory, but pass TokenFactory into jwtOptionsProvider:
@Injectable()
export class TokenManager extends TokenFactory {
// You can pass deps from @auth0/angular-jwt
constructor(@Inject(localStorage) protected localStorage: any,
private jwtHelper: JwtHelperService) {
super(localStorage);
}
// Other methods...
}
Hi all, FTR, I was facing the same issue, the problem is that we need to inject a service in the jwtOptionsFactory but this service is also provide in the module providers.
it was tricky, maybe not the best, but I can solved the issue on that way:
app.module.ts
// [..]
import { JwtModule, JWT_OPTIONS } from '@auth0/angular-jwt';
import { jwtOptionsFactory } from './authentication/jwtOptions.factory'
// [..]
import { AuthService } from './authentication/auth.service';
import { ConfigService } from './services/config.service';
@NgModule({
imports: [
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useClass: jwtOptionsFactory
}
})
],
// [...]
providers: [
AuthService,
ConfigService,
// [..]
jwtOptions.factory.ts
import { Injector, Injectable } from '@angular/core';
import { AuthService } from './auth.service';
import { ConfigService } from '../services/config.service';
// https://github.com/auth0/angular2-jwt/issues/416
@Injectable()
export class jwtOptionsFactory {
private authService: AuthService;
private configService: ConfigService;
public skipWhenExpired: boolean = true;
public whitelistedDomains: string[];
public blacklistedRoutes: string[];
constructor(inj: Injector) {
// https://github.com/angular/angular/issues/18224
// https://github.com/angular/angular/issues/18224#issuecomment-316951787
setTimeout(() => {
this.authService = inj.get(AuthService);
this.configService = inj.get(ConfigService);
this.whitelistedDomains = this.configService.get('environment.jwt.whitelistedDomains');
this.blacklistedRoutes = this.configService.get('environment.jwt.blacklistedRoutes');
});
}
public tokenGetter = () => this.authService.getToken();
}
I was having the same issue, but with @xavadu workaround is solved...
Most helpful comment
I have the same issue, but I still don't know how to resolve it.
I import the JwtModule with the forRoot() stuff in my main app.module like this:
The jwtOptionsFactory looks like this:
Both the JwtHelperService and the HttpClient get injected into the AuthService, because it implements the token refreshing logic, too.
The resulting error looks like this:
The AuthService is placed inside its own AuthModule, which is also included (with forRoot()) in the appModule. The JwtModule is only included in the AppModule though.
Oh another maybe useful info: I'm using my own (second) interceptor to handle token refresh logic, which depends on the AuthService, too.
Is there something I did wrong?