Why is jquery's .ajax() method not sending my session cookie?

后端 未结 11 1524
长情又很酷
长情又很酷 2020-11-22 02:25

After logging in via $.ajax() to a site, I am trying to send a second $.ajax() request to that site - but when I check the headers sent using FireB

相关标签:
11条回答
  • 2020-11-22 03:06

    If you are developing on localhost or a port on localhost such as localhost:8080, in addition to the steps described in the answers above, you also need to ensure that you are not passing a domain value in the Set-Cookie header.
    You cannot set the domain to localhost in the Set-Cookie header - that's incorrect - just omit the domain.

    See Cookies on localhost with explicit domain and Why won't asp.net create cookies in localhost?

    0 讨论(0)
  • 2020-11-22 03:07

    AJAX calls only send Cookies if the url you're calling is on the same domain as your calling script.

    This may be a Cross Domain Problem.

    Maybe you tried to call a url from www.domain-a.com while your calling script was on www.domain-b.com (In other words: You made a Cross Domain Call in which case the browser won't sent any cookies to protect your privacy).

    In this case your options are:

    • Write a small proxy which resides on domain-b and forwards your requests to domain-a. Your browser will allow you to call the proxy because it's on the same server as the calling script.
      This proxy then can be configured by you to accept a cookie name and value parameter which it can send to domain-a. But for this to work you need to know the cookie's name and value your server on domain-a wants for authentication.
    • If you're fetching JSON objects try to use a JSONP request instead. jQuery supports these. But you need to alter your service on domain-a so that it returns valid JSONP responds.

    Glad if that helped even a little bit.

    0 讨论(0)
  • 2020-11-22 03:10

    Just my 2 cents on setting PHPSESSID cookie issue when on localhost and under dev environment. I make the AJAX call to my REST API endpoint on the locahost. Say its address is mysite.localhost/api/member/login/ (virtal host on my dev environment).

    • When I do this request on Postman, things go fine and PHPSESSID is set with the response.

    • When I request this endpoint via AJAX from the Browsersync proxied page (e.g. from 122.133.1.110:3000/test/api/login.php in my browser address line, see the domain is different vs mysite.localhost) PHPSESSID does not appear among cookies.

    • When I make this request directly from the page on the same domain (i.e. mysite.localhost/test/api/login.php) PHPSESSID is set just fine.

    So this is a cross-origin origin request cookies issue as mentioned in @flu answer above

    0 讨论(0)
  • 2020-11-22 03:16

    I am operating in cross-domain scenario. During login remote server is returning Set-Cookie header along with Access-Control-Allow-Credentials set to true.

    The next ajax call to remote server should use this cookie.

    CORS's Access-Control-Allow-Credentials is there to allow cross-domain logging. Check https://developer.mozilla.org/En/HTTP_access_control for examples.

    For me it seems like a bug in JQuery (or at least feature-to-be in next version).

    UPDATE:

    1. Cookies are not set automatically from AJAX response (citation: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/)

      Why?

    2. You cannot get value of the cookie from response to set it manually (http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader)

      I'm confused..

      There should exist a way to ask jquery.ajax() to set XMLHttpRequest.withCredentials = "true" parameter.

    ANSWER: You should use xhrFields param of http://api.jquery.com/jQuery.ajax/

    The example in the documentation is:

    $.ajax({
       url: a_cross_domain_url,
       xhrFields: {
          withCredentials: true
       }
    });
    

    It's important as well that server answers correctly to this request. Copying here great comments from @Frédéric and @Pebbl:

    Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *

    So when the request is:

    Origin: http://foo.example
    Cookie: pageAccess=2
    

    Server should respond with:

    Access-Control-Allow-Origin: http://foo.example
    Access-Control-Allow-Credentials: true
    
    [payload]
    

    Otherwise payload won't be returned to script. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials

    0 讨论(0)
  • 2020-11-22 03:22

    Adding my scenario and solution in case it helps someone else. I encountered similar case when using RESTful APIs. My Web server hosting HTML/Script/CSS files and Application Server exposing APIs were hosted on same domain. However the path was different.

    web server - mydomain/webpages/abc.html

    used abc.js which set cookie named mycookie

    app server - mydomain/webapis/servicename.

    to which api calls were made

    I was expecting the cookie in mydomain/webapis/servicename and tried reading it but it was not being sent. After reading comment from the answer, I checked in browser's development tool that mycookie's path was set to "/webpages" and hence not available in service call to

    mydomain/webapis/servicename

    So While setting cookie from jquery, this is what I did -

    $.cookie("mycookie","mayvalue",{**path:'/'**});
    
    0 讨论(0)
提交回复
热议问题