AngularJS $http POST withCredentials fails with data in request body

10,301

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

  1. 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.
  2. And if POST has request data:
    • Content-Type MUST BE either of the followings:
      • application/x-www-form-urlencoded
      • multipart/form-data
      • text/html

This SIMPLE version clearly IS NOT your case...

Preflighted CORS Version

  1. 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.
  2. 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.

This PREFLIGHTED version clearly IS your case...

Requests with Credentials

  1. 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...

Share:
10,301
Amir Jamak
Author by

Amir Jamak

Updated on June 05, 2022

Comments

  • Amir Jamak
    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:

    CORS $http request without body

    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:

    CORS $http request with body fails!

    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.