angular: HttpClient does not set X-XSRF-Token on Http Post
I’m submitting a…
[ ] 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<Models.Sample[]> {
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<Models.Sample[]> {
let body = JSON.stringify(sample)
return this.httpClient
.post<Models.Task[]>(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:
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 36
- Comments: 54 (2 by maintainers)
Commits related to this issue
- Remind the user to omit the protocol prefix for POST, DELETE and PUT requests, else Angular will not provide an XSRF header. Example: `gatewayUri = '//localhost:8080'`. See https://github.com/angular... — committed to eayin2/spring-addons by deleted user 6 months ago
- Remind the user to omit the protocol prefix for POST, DELETE and PUT requests, else Angular will not provide an XSRF header. Example: `gatewayUri = '//localhost:8080'`. See https://github.com/angular... — committed to eayin2/spring-addons by deleted user 6 months ago
- - If the frontend is not SAMEORIGIN, then prefix the API URI with the gateway domain, but without the protocol prefix, otherwise Angular will not provide a CSRF header for POST/DELETE/PUT requests. ... — committed to eayin2/spring-addons by deleted user 6 months ago
- Remind the user to omit the protocol prefix for POST, DELETE and PUT requests in Angular (#170) * Remind the user to omit the protocol prefix for POST, DELETE and PUT requests, else Angular will not... — committed to ch4mpy/spring-addons by eayin2 6 months ago
Hello, we reviewed this issue and determined that it doesn’t fall into the bug report or feature request category. This issue tracker is not suitable for support requests, please repost your issue on StackOverflow using tag
angular
.If you are wondering why we don’t resolve support issues via the issue tracker, please check out this explanation.
You’re probably after https://angular.io/api/common/http/HttpClientXsrfModule
@bhanukumar04 If you look at Angular’s
xsrf
implementation here You can see in the interceptor they have thisIf any of the condition are true then adding the header is skipped. That’s why I had to make my own since my API is on a different domain.
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.
Same problem Angular 5.2.5 with Spring boot 1.5.4. I’ve tried all solutions including writing my own interceptor, but am getting null on
let token = this.tokenExtractor.getToken() as string;
@bhanukumar04 I just created an Interceptor and did it myself.
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.
Any update? I have my XSRF-TOKEN non-HttpOnly and angular still does not set X-XSRF-TOKEN
Then the italic is a better choice 😃
After struggling for countless hours, the solution that worked for us was changing the request (in Angular) from ‘https://example.com’ to ‘//example.com’.
None of the other solutions worked for us.
IIRC:
HttpClientXsrfModule
does not add the header on requests using absolute urls.HttpClientXsrfModule
does not add the header unless the path is set to/
.HttpClientXsrfModule
does not add the header unless the cookie is set tohttpOnly=false
.Why has this information not been in the documentation for almost five years?
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.
On Stack Overflow there’s a nice comment about this issue which also states that some part of the Angular documentation isn’t precise in terms of X-XSRF-Token, link https://stackoverflow.com/a/50511663/11127383
@JMoney417
Hope it helps. Google point 4 😃
@merv0190 Geez, why are you shouting?
Does anyone can help me in modifying the below code written
As I’m Unable to generate cookies and add the XSRF Token So the XSRF Token must be printed in the backend of my PHP script As I’ve Seen from the @bhanukumar04 and rest of the users getting successfull
Here is my below code in an Angular 6
Since I’ve changed the apiURL = “http://localhost/simple_api/insert.php”; TO apiURL = “//localhost/simple_api/insert.php”;
Working Fine. But unable var_dump or print the the headers attached in the PHP script. But I’m getting the form data submitted successfully.
Had exact same issue. Frontend runs on path
"/"
. Backend runs on path"/myApp"
. Backend was setting cookie path as"/myApp"
. Changing it to"/"
fixed my problem.Actually, I consider it a bug that
//example.com
works - that’s just an absolute path that we don’t detect, the only difference is that the protocol is implied.In general I agree our documentation could be a lot better here. Marking this as a confusing behavior.
That is what is meant with absolute path. It does not work with absolute path. The change you made was to a relative path and that is why it is now working. ‘https://example.com’ < absolute path ‘//example.com’ relative path
@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: https://github.com/angular/angular/issues/20511#issuecomment-955607609
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.
My Two Cents:
To me this is not only a confusing behavior but a missing feature, I’d say a very important one! Not only this doesn’t work in development mode when we use different ports, but it doesn’t work even when the absolute URL points to the same first level domain:
myapp.com
api.myapp.com
I can see 2 possible solutions:
To my knowledge there isn’t because, absolute path means that the URL your trying to make a request to is not on the same domain. And cookies are domain binded. I’m guessing your on ‘http://www.firstweb.com’ and want to make a request to ‘http://www.secondweb.com/getBooks’. If not then you could just do relativepath ‘/getbooks’ instead of ‘http://www.firstweb.com/getBooks’
Hope it helps!
There are a few conditions that must be satisfied for this to work.
Angular: 5.2.9 still same problem