Search code examples
jqueryajaxxmlhttprequestsetcookie

Ajax call to API and passing Set-Cookie


I'm accessing an API, and I have to post a login first. Here is an example of what I'm passing and I get successful connection:

$.ajax({
        type: 'POST',
        url: 'https://server:port/api/users/_login',
        contentType: 'application/x-www-form-urlencoded',
        dataType: 'xml',
        data: {username: "user", password: "userPassword"},
        success: function(data, textStatus, jqXHR){ alert(textStatus); },
        error: function(jqXHR, textStatus, errorThrown){ alert(textStatus); }
        });

And this is the 200 response:

Access-Control-Allow-Headers:Content-Type
Access-Control-Allow-Methods:GET, POST, DELETE, PUT
Access-Control-Allow-Origin:*
Content-Length:125
Content-Type:application/xml
Date:Fri, 21 Oct 2016 08:49:21 GMT
Expires:Thu, 01 Jan 1970 00:00:00 GMT
Server:Jetty(9.2.14.v20151106)
Set-Cookie:JSESSIONID=h9823inizvhd2793nuqw7;Path=/api;Secure

Any subsequent calls need to be made along with the JSESSIONID. So I wrote another call as follows - the comment fields will show you what I've tried and played round with:

$.ajax({
            type: 'GET',
            url: 'https://server:port/api/datareq/guid/stats',
            dataType: 'xml',
            //crossDomain: true,
            xhrFields: { withCredentials: true },
            //data: data,
            success: function(data, textStatus, jqXHR){ alert(textStatus); },
            error: function(jqXHR, textStatus, errorThrown){ alert(textStatus);}
        });

If I don't include the 'withCredentials' (or set it to false), I just get a 401: unauthorised on the call. However, if I do use the flag I get this message:

A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'null' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.

Now I understand what's happening, but I can't figure a way round it. Read quite a few stack posts but nothing really working. I don't have access to the api web server to make any changes on that side unfortunately, it's a locked down appliance. I'm going to still have a look round for some relevant articles but if someone knows and can shed a bit of light on a workaround, it would be hugely appreciated.

Testing platform: Windows 8.1

Browser: Chrome 53.0.2785.143 (Official Build) m (32-bit)


Solution

  • Unfortunately you have a problem with the browser's same-origin policy, therefore as far as I know, this is unsolvable in the way you tried to solve it. This implies that the approach should be changed. Here is what I propose:

    • implement a server-side function which will send a request based on your client-side request. This request will target the target url
    • the server-side function should take the response of the target site and return it to the browser
    • request your function instead of directly requesting the other site

    Thus, your server-side will be used as a proxy to walk around the same-origin policy.

    https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy