Using Angular 6, I have tried many different approaches over the last two days, with the latest riffing off of this post: https://stackoverflow.com/a/47401544. However, the header is still not being set on requests.
import {Inject, Injectable} from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse,
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class AuthTokenInterceptor implements HttpInterceptor {
constructor() {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do((event: HttpEvent<any>) => {
if (localStorage.getItem('id_token') != null) {
// Clone the request to add the new header.
const request = req.clone({
setHeaders: {
'Content-Type' : 'application/json; charset=utf-8',
'Accept' : 'application/json',
'Authorization': `Bearer ${localStorage.getItem('id_token')}`
}
});
return next.handle(request);
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
console.log('redirect auth interceptor')
// do a redirect
}
}
});
}
}
If I log out request
, the request.headers.lazyUpdate
array is being updated with 3 items, but I don't see the Authorization
header in the request it's intercepting.
request.headers.lazyUpdate
:
{name: "Content-Type", value: "application/json; charset=utf-8", op: "s"}
{name: "Accept", value: "application/json", op: "s"}
{name: "Authorization", value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2Mzh9.tLTmPK46NhXSuqoCfZKgZcrQWzlNqLMI71-G0iy3bi8", op: "s"}
(request.headers.headers
is empty---could this be the problem?)
app.module.ts:
providers: [
{provide: HTTP_INTERCEPTORS, useClass: AuthTokenInterceptor, multi: true},
],
What leads me to think it's an interceptor issue is that if I manually add the headers to the request, I don't get a 401
and the request returns the proper data and a 200
:
return this.http.get(environment.API_URL + 'list/supervise/' + encodeURIComponent(id),
{headers: new HttpHeaders().set('Authorization', `Bearer ${localStorage.getItem('id_token')}`)}).pipe(
map((res: any) => res.data)
);
Is there anything I may be overlooking? Thanks.
EDIT:
As I mention in a comment below, I was returning next.handle
twice. This is the solution I ended up going with:
import {Injectable} from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthTokenInterceptor implements HttpInterceptor {
constructor() {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = localStorage.getItem('id_token');
req = req.clone({
setHeaders: {
'Authorization': `Bearer ${token}`
},
});
return next.handle(req);
}
}
Full solution I went with:
import {Injectable} from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthTokenInterceptor implements HttpInterceptor {
constructor() {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = localStorage.getItem('id_token');
req = req.clone({
setHeaders: {
'Authorization': `Bearer ${token}`
},
});
return next.handle(req);
}
}
You could try a simpler version of it.(just like your reference link does
)
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const jwt = localStorage.getItem('id_token');
if (!!jwt) {
req = req.clone({
setHeaders: {
Authorization: `Bearer ${jwt}`
}
});
}
return next.handle(req);
}
You don't have to handle the error
here
since the point of intercepter
here(in your context) is to clone(that means whenever we took request, we clone it, then do whatever we want and send it away).
We could add more headers more data
And it will be sent away, then eventually coming back with return from Api
And leave the handle problem to the service
that call the httpRequest
(eg: then, catch, pipe
,...).
Again, you declared this in app.module.ts
which mean all
of the request
to api in your app will be intercept, and what if I want to handle a specific request with the error message Nothing here
?, and if you do some complicated logic, it could affect all request.
And about your code above, I haven't try it, but I think their could be something wrong happened when you nested like that or so, you should put the break point their and tried to debug what happened.
So the first issue i see here is that u dont return if there is no value in localStorage. i would structure the interceptor like this:
export class AuthInterceptor implements HttpInterceptor {
private APIToken = null;
private defaultApplicationHeaders = {
'Content-Type': 'application/json'
}
buildRequestHeaders():HttpHeaders {
let headers = this.defaultApplicationHeaders;
// set API-Token if available
if(this.APIToken !== null) {
let authHeaderTpl = `Bearer ${this.APIToken}`;
headers['Authorization'] = authHeaderTpl
}
return new HttpHeaders(headers);
}
constructor() {
this.APIToken = localStorage.getItem('id_token')
}
intercept(req: HttpRequest<any>, next: HttpHandler) {
const headers = this.buildRequestHeaders();
const authReq = req.clone({ headers });
return next.handle(authReq);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With