You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
HttpClient does not set X-XSRF-Token on Http Post #20511
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
Updated to angular 5.0.2. Updated from the deprecated HttpModule (@angular/http) to HttpClientModule (@angular/common/http).
Updated Http.post to HttpClient.post and tested. X-XSRF-TOKEN was not present in the Http Header.
HttpClient (@angular/common/http) does not set X-XSRF-Token on Http Post, while Http (@angular/http) does.
Expected behavior
HttpClient should set the X-XSRF-TOKEN on Http Post.
Minimal reproduction of the problem with instructions
Verify that javascript XSRF-TOKEN cookie has been set.
Test HttpClient (@angular/http) and HttpClientModule (@angular/common/http) side by side with nearly identical Http post requests.
//OLD
CreateOld(sample: Models.Sample): Observable {
let body = JSON.stringify(sample);
let headers = new Headers({ 'Content-Type': 'application/json' });
return this.http
.post(this.baseUrl + 'api/sample/Create', body, { headers: headers })
.map(response => { return response.json() as Models.Task[] });
}
//NEW
CreateNew(sample: Models.Sample): Observable {
let body = JSON.stringify(sample)
return this.httpClient
.post(this.baseUrl + 'api/sample/Create', body, { headers: new HttpHeaders().set('Content-Type', 'application/json') });
}
What is the motivation / use case for changing the behavior?
Environment
Angular version: 5.0.2
Browser:
- [ X] Chrome (desktop) version 62.0.3202.94
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [X ] Edge version 41.16299.15.0
For Tooling issues:
- Node version: XX
- Platform:
Others:
Yes, we already have that implemented. Still an issue.
Per your documentation on HttpClientModule, please see the section in bold. This is either a bug or a invalid documentation.
"Security: XSRF Protection
Cross-Site Request Forgery (XSRF) is an attack technique by which the attacker can trick an authenticated user into unknowingly executing actions on your website. HttpClient supports a common mechanism used to prevent XSRF attacks. When performing HTTP requests, an interceptor reads a token from a cookie, by default XSRF-TOKEN, and sets it as an HTTP header, X-XSRF-TOKEN. Since only code that runs on your domain could read the cookie, the backend can be certain that the HTTP request came from your client application and not an attacker.
By default, an interceptor sends this cookie on all mutating requests (POST, etc.) to relative URLs but not on GET/HEAD requests or on requests with an absolute URL.
To take advantage of this, your server needs to set a token in a JavaScript readable session cookie called XSRF-TOKEN on either"
I have found another bug report #18859, "HttpClient HttpXsrfInterceptor does not set xsrf token for absolute urls" which is a duplicate of this issue.
Reacted by spring1975, Ruslan, HighMaster, Martial DERRIEN, Miguel Wolf, Dasith Wijesiriwardena, ✅ Daniel Danielecki and Frédéric
I am also facing the same issue with angular 4. I can see the cookie in the response headers but while posting data angular is not adding appropriate headers , also I have tried with HttpClientXsrfModule.
Reacted by Miroslav Jonaš, cnicho, houabidi, Jin Liang, lgangloff, Victoria Do, David, spring1975, julaudo, Hari Prasad M and 11 more
am also facing the same issue with Angular 5.2.X version, is there any work around for it. In the first request am getting XSRF-TOKEN cookie in response and in the next requests am expecting to add cookie by angular which is not happening and my XSRF-TOKEN non-HttpOnly.
Reacted by Ruslan, Chris Kelley, Miguel Wolf and Artem Lysenko
@bhanukumar04 I just created an Interceptor and did it myself.
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let requestToForward = req;
let token = this.tokenExtractor.getToken() as string;
if (token !== null) {
requestToForward = req.clone({ setHeaders: { "X-XSRF-TOKEN": token } });
}
return next.handle(requestToForward);
}
Reacted by Bhanu Kumar, Olga Grabek, Choubani Amir, Imtiaz Shakil Siddique, Robbie Fryers, Victor Hugo Mello, Martin Weber, Navnit Anuth and Mohamedarsath
Since today , it is very common to have UI (angular) and business logic to be situated in different machines (hence different origin), thus angular should be updated to allow include X-XSRF automatically , and not worry about same or different origin. Or at least provide an option for developer to enable this.
+1 to this issue,
I spent +24 hours trying to figure out what was wrong, it almost made me cry, I thought it was the server, so I started from scratch like 10 times, until I decided to try with axios, and I found out that the error was that the X-XSRF-TOKEN was not automatically added to the headers, I added it manually and it worked, then I found this post on stack overflow that shows a workaround, and then I finally discover this issue.
It worked with the relative path //localhost:8000, as everyone mentioned it is really confusing, can someone explain why absolute paths don't work ? I didn't even know it was possible to use relative paths, and it feels weird, we are in the 15.x version of angular, this definitely needs to be fixed or to be documented, to avoid other devs to waste time
@Loque18 Your issue: "Documenting things to keep devs from wasting their time" was reported and immediately closed as "not a priority" during the Angular 2 RC process.
Any Angular codebase is going to be filled with notes about undocumented behaviors and workarounds for obvious defects that reference years old tickets.
it almost made m[e] cry
Welcome to the club, we had jackets made.. So many tear stained jackets.
+1 to this issue, I spent +24 hours trying to figure out what was wrong, it almost made me cry, I thought it was the server, so I started from scratch like 10 times, until I decided to try with axios, and I found out that the error was that the X-XSRF-TOKEN was not automatically added to the headers, I added it manually and it worked, then I found this post on stack overflow that shows a workaround, and then I finally discover this issue.
It worked with the relative path //localhost:8000, as everyone mentioned it is really confusing, can someone explain why absolute paths don't work ? I didn't even know it was possible to use relative paths, and it feels weird, we are in the 15.x version of angular, this definitely needs to be fixed or to be documented, to avoid other devs to waste time
I faced the same issue while integrating the Laravel Breeze (Santumn) API backend. And I am not sure yet how to work around this.
Here is my interceptor:
import{HttpErrorResponse,HttpEvent,HttpHandlerFn,HttpRequest,}from'@angular/common/http';import{inject}from'@angular/core';import{AuthService}from'app/core/auth/auth.service';import{Observable,catchError,throwError}from'rxjs';/** * Intercept * * @param req * @param next */exportconstauthInterceptor=(req: HttpRequest<unknown>,next: HttpHandlerFn): Observable<HttpEvent<unknown>>=>{const authService =inject(AuthService);console.log('req :>> ',req);constauthReq=req.clone({withCredentials: true,// Ensures cookies are sent with the requestheaders: req.headers.set('X-Requested-With','XMLHttpRequest'),});console.log('authReq :>> ',authReq);returnnext(authReq).pipe(catchError((error: any)=>{// If we receive a 401 Unauthorized response, logout the userif(errorinstanceofHttpErrorResponse&&error.status===401){authService.signOut();// location.reload();}returnthrowError(()=>error);}));};
By default, an interceptor sends this header on all mutating requests (such as POST) to relative URLs, but not on GET/HEAD requests or on requests with an absolute URL.
Activity
Toxicable commentedon Nov 18, 2017
justin-ruffin commentedon Nov 18, 2017
Yes, we already have that implemented. Still an issue.
Per your documentation on HttpClientModule, please see the section in bold. This is either a bug or a invalid documentation.
"Security: XSRF Protection
Cross-Site Request Forgery (XSRF) is an attack technique by which the attacker can trick an authenticated user into unknowingly executing actions on your website. HttpClient supports a common mechanism used to prevent XSRF attacks. When performing HTTP requests, an interceptor reads a token from a cookie, by default XSRF-TOKEN, and sets it as an HTTP header, X-XSRF-TOKEN. Since only code that runs on your domain could read the cookie, the backend can be certain that the HTTP request came from your client application and not an attacker.
By default, an interceptor sends this cookie on all mutating requests (POST, etc.) to relative URLs but not on GET/HEAD requests or on requests with an absolute URL.
To take advantage of this, your server needs to set a token in a JavaScript readable session cookie called XSRF-TOKEN on either"
I have found another bug report #18859, "HttpClient HttpXsrfInterceptor does not set xsrf token for absolute urls" which is a duplicate of this issue.
sajagekar commentedon Nov 20, 2017
I am also facing the same issue with angular 4. I can see the cookie in the response headers but while posting data angular is not adding appropriate headers , also I have tried with HttpClientXsrfModule.
ewaschenko commentedon Feb 9, 2018
Any update? I have my XSRF-TOKEN non-HttpOnly and angular still does not set X-XSRF-TOKEN
bhanukumar04 commentedon Mar 9, 2018
am also facing the same issue with Angular 5.2.X version, is there any work around for it. In the first request am getting XSRF-TOKEN cookie in response and in the next requests am expecting to add cookie by angular which is not happening and my XSRF-TOKEN non-HttpOnly.
ewaschenko commentedon Mar 9, 2018
@bhanukumar04 I just created an Interceptor and did it myself.
49 remaining items
hannah23280 commentedon Jan 2, 2023
Since today , it is very common to have UI (angular) and business logic to be situated in different machines (hence different origin), thus angular should be updated to allow include X-XSRF automatically , and not worry about same or different origin. Or at least provide an option for developer to enable this.
Loque18 commentedon Feb 11, 2023
+1 to this issue,
I spent +24 hours trying to figure out what was wrong, it almost made me cry, I thought it was the server, so I started from scratch like 10 times, until I decided to try with axios, and I found out that the error was that the X-XSRF-TOKEN was not automatically added to the headers, I added it manually and it worked, then I found this post on stack overflow that shows a workaround, and then I finally discover this issue.
It worked with the relative path //localhost:8000, as everyone mentioned it is really confusing, can someone explain why absolute paths don't work ? I didn't even know it was possible to use relative paths, and it feels weird, we are in the 15.x version of angular, this definitely needs to be fixed or to be documented, to avoid other devs to waste time
this is my code just in case anyone need it
michaelurban commentedon Feb 11, 2023
@Loque18 Your issue: "Documenting things to keep devs from wasting their time" was reported and immediately closed as "not a priority" during the Angular 2 RC process.
This is what I found as of a few years ago: #20511 (comment)
Any Angular codebase is going to be filled with notes about undocumented behaviors and workarounds for obvious defects that reference years old tickets.
Welcome to the club, we had jackets made.. So many tear stained jackets.
RNX339 commentedon May 26, 2023
Solution :
csrf-interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpEvent,
HttpXsrfTokenExtractor,
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class CsrfInterceptor implements HttpInterceptor {
constructor(private csrfExtract: HttpXsrfTokenExtractor) {}
intercept(
req: HttpRequest,
next: HttpHandler
): Observable<HttpEvent> {
// Get csrf from the cookie.
const csrf = this.csrfExtract.getToken()?.toString() || '';
// Clone the request and replace the original headers with
// cloned headers, updated with csrf.
const csrfReq = req.clone({
headers: req.headers.set('X-XSRF-TOKEN', csrf),
withCredentials: true,
});
}
}
app.modules.ts
...
providers: [
[{ provide: HTTP_INTERCEPTORS, useClass: CsrfInterceptor, multi: true }],
],
Remind the user to omit the protocol prefix for POST, DELETE and PUT …
Remind the user to omit the protocol prefix for POST, DELETE and PUT …
- If the frontend is not SAMEORIGIN, then prefix the API URI with the…
Remind the user to omit the protocol prefix for POST, DELETE and PUT …
lodistack commentedon Oct 3, 2024
I faced the same issue while integrating the Laravel Breeze (Santumn) API backend. And I am not sure yet how to work around this.
Here is my interceptor:
JeanMeche commentedon Oct 1, 2025
The documentation does mention:
https://angular.dev/best-practices/security#httpclient-xsrf-csrf-security
Today this is a hard coded configuration.
angular/packages/common/http/src/xsrf.ts
Lines 106 to 114 in 1cb16fd
fix(http): enable XSRF protection for same-origin absolute URLs
fix(http): enable XSRF protection for same-origin absolute URLs
angular-automatic-lock-bot commentedon Jan 3, 2026
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.