I've read the docs and all the related questions on SO, but still Angular's XSRF mechanism isn't working for me: in no way I can make a POST request with the X-XSRF-TOKEN header appended automatically.
I have an Angular 6 app with a login form.
It's part of a Symfony (PHP 7.1) website, and the Angular app page, when served from Symfony, sends the correct Cookie (XSRF-TOKEN
):
My app.module.ts includes the right modules:
// other imports... import {HttpClientModule, HttpClientXsrfModule} from "@angular/common/http"; // ... @NgModule({ declarations: [ // ... ], imports: [ NgbModule.forRoot(), BrowserModule, // ... HttpClientModule, HttpClientXsrfModule.withOptions({ cookieName: 'XSRF-TOKEN', headerName: 'X-CSRF-TOKEN' }), // other imports ], providers: [], entryComponents: [WarningDialog], bootstrap: [AppComponent] }) export class AppModule { }
Then, inside a Service's method, I'm making the following http request (this.http
is an instance of HttpClient
):
this.http .post<any>('api/login', {'_username': username, '_pass': password}) .subscribe(/* handler here */);
The post request never sends the X-XSRF-TOKEN header. Why?
It is added to the request header for ajax requests. Popular libraries like angular and axios , automatically get value of this header from xsrf-token cookie and put it in every request header.
The XSRF-TOKEN cookie is both httponly and secure, it is getting decrypted accurately and it does match up with the token stored for the session on the server.
HttpClientXsrfModulelinkConfigures XSRF protection support for outgoing requests.
The problem once again is Angular's poor documentation.
The fact is, Angular will add the X-XSRF-TOKEN
header only if the XSRF-TOKEN
cookie was generated server-side with the following options:
/
false
(this is very important, and fully undocumented)Besides, the Angular app and the URL being called must reside on the same server.
Reference: this Angular Github issue
On my team, the problem was that we were using an absolute path instead of a relative path.
So do not use an absolute path like:
this.http.post<any>("https://example.com/api/endpoint",data)
Use
this.http.post<any>("api/endpoint",data)
Or use
this.http.post<any>("//example.com/api/endpoint",data)
This is because absolute paths are explicitly ignored by Angular code on HttpClientXsrfModule (see)
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