AngularJS $http POST withCredentials fails with data in request body
Solution 1
According to Cross-Origin Request with Preflight specs credentials, i.e. session cookie, is not sent within the preflight request, therefore the solution is to disable security on OPTIONS requests on your REST server side and allow requests without session cookie only for OPTIONS requests.
Of course be careful to not disable security for POST and GET requests.
Solution 2
Amir,
Allow me to help you and others clearly understand what is expected when dealing with CORS, as such:
Index:
- Simple CORS Version
- Preflighted CORS version
- Requests with Credentials
Simple CORS Version
- You can use GET, HEAD or POST:
- In any of the method cases, you CANNOT set custom headers.
- You can always have the server side restrict domain access through Access-Control-Allow-Origin header.
- And if POST has request data:
- Content-Type MUST BE either of the followings:
- application/x-www-form-urlencoded
- multipart/form-data
- text/html
- Content-Type MUST BE either of the followings:
This SIMPLE version clearly IS NOT your case...
Preflighted CORS Version
- You can use GET, HEAD or POST:
- In any of the method cases, you CAN set custom headers.
- You can always have the server side restrict domain access through Access-Control-Allow-Origin header.
- And if POST has request data:
- Content-Type MAY BE of the followings:
- application/x-www-form-urlencoded
- multipart/form-data
- text/html
- Content-Type CAN ALSO BE of other types:
- application/json
- application/xml
- text/xml
- etc.
- Content-Type MAY BE of the followings:
This PREFLIGHTED version clearly IS your case...
Requests with Credentials
- If your invoking calls with cookies, you need to set the following parameter part of your request:
- withCredentials = true
Requests with Credentials clearly IS your case as well...
Amir Jamak
Updated on June 05, 2022Comments
-
Amir Jamak almost 2 years
AngularJS authenticates against server side using REST, and gets the JSESSIONID cookie. In the next step I am trying to get some JSON data from server side using REST along with the session cookie gained in the previous step. Here is the client-side code:
getSomeJSONDataFromServer:function() { var deferred = $q.defer(); $http({ method: 'POST', withCredentials: true, url: "http://domain.name/app/someURL", headers:{ 'Accept':'application/json', 'Content-Type':'application/json; charset=utf-8', 'Access-Control-Request-Headers': 'X-Requested-With, content-type, accept, origin, withcredentials' } }) .success(function(data, status, headers, config) { // handle data }) .error(function(data, status, headers, config) { // handle error }); return deferred.promise; }
The code above works OK:
The problems start when I send some data in the above POST request body.
... $http({ method: 'POST', withCredentials: true, url: "http://domain.name/app/someURL", headers:{ 'Accept':'application/json', 'Content-Type':'application/json; charset=utf-8', 'Access-Control-Request-Headers': 'X-Requested-With, content-type, accept, origin, withcredentials' }, data: '{}' }) .success(...
The above code fails in the prelight request:
Looks like the server starts a new session because the session cookie is not sent for some reason. Anyway, I feel like I am missing something really simple, some header or something like that... Any ideas are appreciated. Thanks in advance.