I am working with JWT (JSON Web Tokens) as a part of logging people into the system. The code that does this is as follows:
this.http.post(url, JSON.stringify({ username: username, password: password }), { observe: 'response' })
.subscribe((response: HttpResponse<any>) => {
When sending the username
and password
to the server, the Response object contains the encrypted authorization in the Header.
Included as part of the headers is an Authorization
entry and also a Pragma
entry. The Authorization
has the token correctly defined (and it works). Pragma
is also defined as no-cache
From Network tab in Chrome:
but when running the code to process the response headers, the Authorization
header is not present.
adminLogin(username, password) {
let url = `${this._apiRoot}/login`;
let tokenResp = {};
this.http.post(url, JSON.stringify({ username: username, password: password }), { observe: 'response' })
.subscribe((response: HttpResponse<any>) => {
console.log(" ---- begin response ----");
console.log( response );
console.log(" ---- end response ----");
let token = response.headers.get("Authorization");
console.log(" ---- begin token ----");
console.log ( token );
console.log(" ---- end token ----");
let pragma = response.headers.get("pragma");
console.log(" ---- begin pragma ----");
console.log ( pragma );
console.log(" ---- end pragma ----");
Results from code executed:
From the code executed, one can see that the trying to find the Authorization
returns null
while Pragma
gets no-cache
. What is going on?
UPDATE
Thanks all for the information.
I followed the information here: https://github.com/angular/angular/issues/13554
and made changes to the java code:
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res, FilterChain chain, Authentication auth)
throws IOException, ServletException {
String username = ((User) auth.getPrincipal()).getUsername();
ApplicationUser user = applicationUserRepository
.findByUsername(username);
String token = Jwts
.builder()
.setSubject(((User) auth.getPrincipal()).getUsername())
.claim("id", user.getId())
[... snip ...]
res.addHeader("Access-Control-Expose-Headers", "Authorization");
res.addHeader(SecurityConstants.HEADER_STRING,SecurityConstants.TOKEN_PREFIX + token);
}
Thanks again!
To solve this issue we need to expose the desired header from the backend side and use and write a custom HttpInterceptor.
NodeJs API exemple: Expose authorization
header from backend
res.setHeader('Access-Control-Expose-Headers', 'authorization');
res.setHeader('authorization', 'foo-bar');
Sample angular interceptor
@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<any> {
return next.handle(request).pipe(
tap(response => {
if (response.headers) {
console.log('Header keys', response.headers.keys());
console.log('Authorization: ', response.headers.get('authorization'));
}
}),
);
}
}
Lastly we add our interceptor to our module providers
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpInterceptorService } from './http-interceptor.service';
@NgModule({
...
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorService, multi: true },
],
})
export class AppModule {}
This sample code and repos can be usefull to know more about Angular HttpInterceptor
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