I have the 1.0.0 version of @auth0/angular-jwt installed (npm install @auth0/[email protected]), as I'm on Angular 5.2, My login is setting the token, I can see it in local storage. However, when I go to post (the function is called addNote below) via http I get an auth issue and see when I inspect the request that there is no header being sent.
This was working earlier, I'm wondering if I had a different version installed. Thanks for taking a look.
here is the relevant code in my app.module.ts:
import { JwtModule } from '@auth0/angular-jwt';
import { HttpClientModule, HttpClient } from '@angular/common/http';
export function tokenGetter() {
return localStorage.getItem('token');
}
Then in my imports:
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(
appRoutes,
{ enableTracing: true } // <-- debugging purposes only
),
HttpClientModule,
JwtModule.forRoot({
config: {
tokenGetter: tokenGetter,
whitelistedDomains: ['localhost:3001', 'http://localhost:8080', 'https://example.herokuapp.com/' ],
blacklistedRoutes: ['localhost:3001/auth/']
}
})
],
My auth service:
import { NgModule } from '@angular/core';
import { Http, RequestOptions, Headers } from '@angular/http';
import { Injectable } from '@angular/core';
import { HttpClientModule, HttpClient, HttpHeaders } from '@angular/common/http';
import { JwtHelperService } from '@auth0/angular-jwt';
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
@Injectable()
export class AuthService {
helper = new JwtHelperService();
constructor(private http: HttpClient, private router: Router){}
public isAuthenticated(): boolean {
const token = localStorage.getItem('token');
console.log("token:", localStorage.getItem('token'));
return !this.helper.isTokenExpired(token);
}
//Then we add the functions that allow users to register, authenticate, and logout
public login(credentials) {
console.log("login attempt", credentials);
this.http.post('https://example.herokuapp.com/api/login', credentials).subscribe(data => {
console.log("login attempt", data);
if(data){
localStorage.setItem('token', data['authToken']);
console.log("token in ", localStorage.getItem('token'));
this.router.navigate(['/notes']);
}
}, error => {
console.log(error);
if (error.status == 401) {
alert("Credentials are not matching: Username or Email is not correct");
}
if (error.status == 400) {
alert("Username or Email is missing");
}
});
}
public logout() {
localStorage.removeItem('token');
}
public register(user) {
this.http.post(' https://example.herokuapp.com/api/users', user).subscribe(data => {
console.log("new user! ", user.fullname)
if(data){
localStorage.setItem('token', data['authToken']);
console.log("token in ", localStorage.getItem('token'));
this.router.navigate(['/notes']);
}
}, error => {
console.log(error);
if (error.status == 422 || error.status == 400)
alert(error.error.message);
});
}
}
My request service:
import { Injectable } from "@angular/core";
import { NOTES } from "./mock-data";
import { Note } from "./models";
import { BaseService } from "./base.service";
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
@Injectable()
export class NotesService {
constructor(private http: HttpClient, private baseService: BaseService) { }
notesUrl = this.baseService.baseUrl + "/notes";
getNotes(): Observable<Note[]> {
return this.http.get<Note[]>(this.notesUrl);
}
addNote (note: Note): Observable<Note> {
return this.http.post<Note>(this.notesUrl, note, httpOptions).pipe(
tap((note: Note) => console.log(`added note w/ id=${note.id}`),
error => {
if (error.status == 400)
alert(error.error.message)
}
)
);
}
deleteNote (id: number): Observable<Note> {
console.log("deleting", id);
return this.http.delete<Note>(this.notesUrl + '/' + id, httpOptions).pipe(
tap((note: Note) => console.log(`deleted note w/ id=${id}`))
);
}
}
well said @SaraJo
having the same problem, i even went so far as to add console.logs to jwt.interceptor.js and its trying to add the token and add heeaders. so it is passing the whitelist in my case. so i wonder if theres an issue w/ the request header and some node version or other dependency. . etc...
console.log('5 adding headers.');
request = request.clone({
setHeaders: (_a = {},
_a[this.headerName] = "" + this.authScheme + token,
_a)
});
console.log('----------- this.authScheme', this.authScheme);
console.log('request----------- this.authScheme', request);
any news? same problem here :-/
I am also having this issue using the Angular CLI and building with AOT. Building without AOT seems to attach the token as expected.
I had a similar problem that was an oversight on my part: just needed to whitelist the domains without a scheme (example.herokuapp.com instead of https://example.herokuapp.com).
I'm not sure it's the same issue because I'm not following what the baseService.baseUrl is in addNote, but the imports file example has schemes in the whitelist. If a new domain was added, it's a easy thing to stick the scheme in by accident.
Turns out my problem was also related to not configuring my domains whitelist correctly for prod builds. Make sure to check your whitelists.
@galenwilk , im new to angular 2+ how do i build w/ ng-cli without aot?
correctly for prod builds.
How so? care to elaborate what was diff in prod ?
@SaraJo @GuilleNorway @galenwilk
my problem was my code seemed to be using http from
import { Http } from '@angular/http';
As opposed to HttpCLIENT
import { HttpClient, HttpHeaders } from '@angular/common/http';
and now i see the header.
maybe the documentation should warn against this explicitly or maybe it does and im blind.
@SaraJo same problem. I had none of the issues mentioned in the comments above.
For future reference, my problem was importing the HttpClientModule in other modules.
Solution: Only import HttpClientModule in the root module.
Thanks @herkulano after many hours, this was the solution
Was having the same issue, caused by a dependency module importing the HttpClientModule as well.
Same issue. In the jwt.interceptor.ts code in lines 53-61
request = request.clone({
setHeaders: (_a = {},
_a[this.headerName] = "" + this.authScheme + token,
_a)
});
put the header to the lazyUpdate list, not to the headers.

Setting up the whitelist domain properly for me did the trick as well.
That is, the domain only, without the https://
In my case, the problem was related to an angular issue here: https://github.com/angular/angular/issues/22829
TL;DR: Angular can't (yet) run any pre-processing code while compiling.
I was attempting to read a URL from my environment file, and extracting its host as so:
environment.ts:
export const environment: Environment = {
api: "http://localhost:5000",
};
auth.ts:
import environment from '../../environment.ts'
// ...
JwtModule.forRoot({
config: {
tokenGetter: tokenGetter,
whitelistedDomains: [getHost(environment.api)]
}
});
export function getHost(url: string): string {
// ...
}
Adding the host explicitly to the environment and using that in auth.ts worked:
export const environment: Environment = {
api: "http://localhost:5000",
host: "localhost:5000" // yucky, but needed due to https://github.com/angular/angular/issues/22829
};
(of course, you can replace api with host, and construct the api elsewhere, but in that case we would need the protocol to be specified i.e. http/https which imo is even yuckier)
Hi everybody, we encountered the same issue.
The only trick which works for us, was to add a flat properties string on our environment.ts files.
In aot, inside the decorator, the RegExp and function seems not to be allowed.
Before (failed in aot)
JwtModule.forRoot({
config: {
tokenGetter,
whitelistedDomains: [
environment.apis.find((api: CoreApiConfig) => api.id === 'myAppApiHost').url.replace(/https?:\/\//, '')
]
}
})
After (works 👍 )
JwtModule.forRoot({
config: {
tokenGetter,
whitelistedDomains: [environment.myAppApiHost]
}
}),
environment.myAppApiHost is just a simple string in the environments files.
@tdervilyIAD your information saved me a looooot of time.
By default the AOT can only consume static values like whitelistedDomains: [environment.myAppApiHost]. Something like whitelistedDomains: [environment.myAppApiHost.split('//')[0]] will work during development, but not after building.
@cre8 thanks a lot we where building whitelist with env.api.split('//')[1] ....
now it works
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you have not received a response for our team (apologies for the delay) and this is still a blocker, please reply with additional information or just a ping. Thank you for your contribution! 🙇♂️
Try to use HttpInterceptor to add authToken into headers:
https://stackoverflow.com/questions/50985669/angular6-angular-jwt-not-adding-token-to-request-headers/61837272#61837272
None of the above solved my issue.
So I downgraded the version from 4.1.1 to 4.0.0. Other versions don't work either.
Token get added now. I am not entirely sure why this happens,
It was working till today. Again came up with the same issue for 4.0.0.
I followed @NiceStepUp example and this https://github.com/bartosz-io/jwt-auth-angular
use a custom interceptor instead.
In my case, i was setting whitelisted domains from enivronment.ts with api version.
like this
whitelistedDomain: ['localhost:5000/api/v1']
after removing the version, everything is fine. so now in my envirnment.ts
whitelistedDomain: ['localhost:5000']
Hope it might help someone. :)
Setting up the whitelist domain properly for me did the trick as well.
That is, the domain only, without the https://
In addition to this, initially I had 3 values in whitelist array. I removed 1 value (localhost one) and it worked. Weird :/
I discovered that the listvalues must be lower case.
Most helpful comment
For future reference, my problem was importing the
HttpClientModulein other modules.Solution: Only import
HttpClientModulein the root module.