I am having this same issue consistently in a prod environment using Angular 5 but It works completely fine locally!
I installed using this command: npm install @auth0/angular-jwt
For a tl;dr - I was previously using Angular 4.4.6 with angular2-jwt, but now that http is deprecated, I am using HttpClient with this newer version of angular-jwt.
Here is what I have done:
My app.module.ts looks as follows (showing both the inline function and a custom factory syntax that I tried)
// app.module.ts
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { JwtModule, JWT_OPTIONS } from '@auth0/angular-jwt';
import { TokenService } from './_services/token.service';
export function jwtOptionsFactory(tokenService) {
return {
tokenGetter: () => {
return tokenService.get();
},
whitelistedDomains: ['budgetivity.com', 'budgetivity.local']
};
}
@NgModule({
declarations: [
AppComponent
],
imports: [
...
HttpClientModule,
JwtModule.forRoot({
config: {
tokenGetter: () => {
return sessionStorage.getItem('token');
},
whitelistedDomains: ['budgetivity.com', 'budgetivity.local']
}
// jwtOptionsProvider: {
// provide: JWT_OPTIONS,
// useFactory: jwtOptionsFactory,
// deps: [TokenService]
// }
}),
I am using full IIS locally with my host file pointing to 127.0.0.1 for budgetivity.local
When I run locally, I am building for dev and I use the ng-build command and my environment.ts looks as follows:
export const environment = {
...
baseUrl: 'http://budgetivity.local',
...
};
When I build for prod I use ng build --env=prod and my environment.prod.ts looks as follows:
export const environment = {
...
baseUrl: 'https://www.budgetivity.com',
...
};
But - when running a ng-build --prod command I get an error if I am using the function syntax instead of the custom service syntax.
"Error encountered resolving symbol values statically. Function calls are not supported."
So when using the ng-build --prod command I must switch the code to only use the custom service syntax.
When running locally, my requests are sucessfully sent to my local API and have an appropriate Authorization: Bearer XXXX (token)
When built for and deployed to Prod, the requests do not have an Authorization header at all.
I have even built for dev but used the Prod baseUrl - when that is deployed to Prod that also does not send the Authorization header in any of the requests.
For sake of completeness here is my tokenService and a method that calls my API:
// token.service.ts
import { Injectable } from '@angular/core';
@Injectable()
export class TokenService {
public get(): string {
return sessionStorage.getItem('token');
}
public set(token: string): void {
sessionStorage.setItem('token', token);
}
public deleteToken(): void {
sessionStorage.removeItem('token');
}
}
// session.service.ts
import { environment } from '../../environments/environment';
...
public isSessionValid(): Observable<any> {
return this.http.get(`${environment.baseUrl}/api/v1/sessions`)
.catch((error: Response) => {
return Observable.throw(error);
});
}
...
Here is what my local call looks like:

and here is what it looks like on Prod:

For what it's worth, I ended up ditching this library altogether.
For determining if a user is still logged in instead of decoding the token on the front end I send a request to my API to a SessionsController that is authorized and simply returns Ok if the authorization attribute logic passes - determines that the token exists in the DB, hasn't expired and hasn't been administratively deactivated. This is much safer and gives the server control of determining if the session is actually valid or not. If it's not valid it returns a 401 and my guard informs the user and signs them out.
// secure.guard.ts
...
@Injectable()
export class SecureGuard implements CanActivate {
constructor(private router: Router,
private alertService: AlertService,
private sessionService: SessionService) { }
public canActivate() {
return this.serverSessionIsValid();
}
public serverSessionIsValid(): Observable<boolean> {
return Observable.create((observer) => {
this.sessionService.isSessionValid().subscribe(
() => {
observer.next(true);
observer.complete();
},
() => {
observer.next(false);
observer.complete();
this.sessionService.clearSession();
this.router.navigate(['/sign-in']);
this.alertService.alert(AlertType.error, 'Your session has expired, you will need to log in.');
});
});
}
...
For adding the authorization header, I just add it to the necessary calls like so:
// session.service.ts
...
public get authHeader(): string {
return `Bearer ${sessionStorage.getItem('token')}`;
}
...
public isSessionValid(): Observable<any> {
return this.http.get(`${environment.baseUrl}/api/v1/sessions`, {
headers: new HttpHeaders().set('Authorization', this.authHeader)
})
.catch((error: Response) => {
return Observable.throw(error);
});
}
...
I am running into same problem.
Me too 馃槩
Me three 馃槶
+1
Same here
+1
Hey! I had the same issue where token wasn't being passed to the server on production. But my issue got resolved by updating the whitelistedDomains array.
JwtModule.forRoot({
config: {
tokenGetter: tokenGetter,
whitelistedDomains: ['localhost:8000','prod-1.app.io','api.prod-2.app.io'],
authScheme: 'JWT '
}
})
I'm also getting same problem
I'm also experiencing the same issue
I am also having the same issue on production with Angular 5. Any solutions?
Solutions that worked for me:
HT to @sambhalgithub. If you're using Angular 6 you have to switch from Http to HttpClient or the authorization header is not appended.
Auth0, it would help if you updated the Readme.MD to specify this.
For anyone still getting this issue when building for production:
I was using a regex replace to remove the protocol from the environment variable. After removing the regex the problem vanished.
// apiEndpoint:https://foo.com
// whitelistedDomains: [ environment.apiEndpoint.replace(/^https?\:\/\//i, '') ]
// apiHost: foo.com
whitelistedDomains: [ environment.apiHost ]
Just configure your app module by this way:
...
import {JwtInterceptor, JwtModule} from '@auth0/angular-jwt';
...
@NgModule({
imports: [
...
JwtModule.forRoot({
config: {
tokenGetter: () => localStorage.getItem('varName'),
whitelistedDomains: ['foo.bar']
}
})
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}
...
],
...
})
Hey! I had the same issue where token wasn't being passed to the server on production. But my issue got resolved by updating the whitelistedDomains array.
JwtModule.forRoot({ config: { tokenGetter: tokenGetter, whitelistedDomains: ['localhost:8000','prod-1.app.io','api.prod-2.app.io'], authScheme: 'JWT ' } })
Thaaanks @hemangsk
whitelistedDomains should be without "http://" or "https://", this was my issue
Heyy @woloski i am still getting this error while ng build --aot
ERROR in Error during template compile of 'AppModule'
Function expressions are not supported in decorators in '傻0'
'傻0' contains the error at src\app\app.module.ts(228,22)
Consider changing the function expression into an exported function
at
JwtModule.forRoot({
config: {
tokenGetter: () => localStorage.getItem('token'),
whitelistedDomains: ['localhost:4200','domain','domain'],
// authScheme: 'JWT '
}
}),
please help me
Thaaanks @youssef-ali
whitelistedDomains should be without "http://" or "https://", this was my issue
Most helpful comment
Hey! I had the same issue where token wasn't being passed to the server on production. But my issue got resolved by updating the whitelistedDomains array.