Search code examples
angularcookiesinterceptorcsrf-protectionx-xsrf-token

how to send "X-CSRF-TOKEN" with response header in angular4


I am currently working on an Angular4 app. Now I want to implement XSRF protection. In Response header cookies, I am getting "XSRF-TOKEN" and I need to send "X-XSRF-TOKEN" in next Request header cookies. As mentioned in official Angular document, Angular is taking care of this. But in my case, angular is not handling it. So I created following custom XsrfInterceptor to attach "X-XSRF-TOKEN" with response header.

import { NgModule, Injectable } from '@angular/core';
import { Observable } from "rxjs/Observable";
import { HttpRequest, HttpHandler, HttpEvent, HttpXsrfTokenExtractor, HttpInterceptor } from "@angular/common/http";

@Injectable()
export class XsrfInterceptor implements HttpInterceptor {

    constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const headerName = 'X-XSRF-TOKEN';
        console.log("xsrf intercepter called");
        let requestToForward = req;
        let token = this.tokenExtractor.getToken() as string;
        console.log(token);
        if (token !== null) {
            requestToForward = req.clone({ setHeaders: {headerName: token } });
        }
        return next.handle(requestToForward);
    }
}

And in my main module, I included it in provider,

providers: [
    LoginService,
    AuthGuardLogin,
    { provide: HTTP_INTERCEPTORS, useClass: XsrfInterceptor,  multi: true }      
], 

But unfortunatley it is not working. I think my aopplication is not calling intercept method of custom Intercepter (it is not printing console.log('xsrf intercepter called')).

My http header is below:

let httpHeader = new RequestOptions({
            headers: new Headers({
                'Content-Type': 'application/json',
                'x-auth-token': this.authToken
            })
        })

In response header:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Access-Control-Allow-Origin, Access-Control-Allow-Headers, Accept, X-XSRF-TOKEN, XSRF-TOKEN, X-Requested-By, Content-Type, Origin, Authorization, X-Requested-With, x-auth-token, OPTIONS
Access-Control-Allow-Methods:POST, GET, PUT, OPTIONS
Access-Control-Allow-Origin:http://localhost:7070
Access-Control-Expose-Headers:x-auth-token, XSRF-TOKEN, X-XSRF-TOKEN
Access-Control-Max-Age:3600
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Date:Fri, 24 Nov 2017 06:42:20 GMT
Expires:0
Pragma:no-cache
Referrer-Policy:same-origin
Set-Cookie:XSRF-TOKEN=63f66e2a-1ad0-4641-8f36-27c16734a676;path=/mfleet;HttpOnly
Transfer-Encoding:chunked
x-auth-token:8d06b1da-c35b-42ea-ac28-eae51f3dd74d
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

Next Request Header:

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.9
Connection:keep-alive
Content-Type:application/json
Cookie:XSRF-TOKEN=63f66e2a-1ad0-4641-8f36-27c16734a676  **//this should be X-XSRF-TOKEN**
Host:localhost:7070
Referer:http://localhost:7070/dist/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
x-auth-token:8d06b1da-c35b-42ea-ac28-eae51f3dd74d

I am using following versions of angular libraries:

"@angular/animations": "^4.4.5",
    "@angular/cdk": "^2.0.0-beta.8",
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "4.0.0",
    "@angular/material": "^2.0.0-beta.8",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/router": "^4.0.0",

Solution

  • Angular is taking care of XSRF only if you import the right module. And only since 4.3 which implement new http client and interceptors.

    You should update angular to at least 4.3.0 (i recommend to upgrade to 5.0.0 cause this is needed for last versions of material2) then import HttpClientXsrfModule in your app module. Then it should work out of the box.

    Regards