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 FireBug, there is no session cookie being included in the request.
What am I doing wrong?
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 FireBug, there is no session cookie being included in the request.
What am I doing wrong?
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:
Glad if that helped even a little bit.
path=/something
and you are requesting the page /another
then the cookie will not be sent. When you request the page /something
the cookie will be sent as expected. So check the code that sets the cookie as well. –
Felisafelise 0.0.0.0:5000
and making AJAX request to localhost:5000
and thinking they are the same. In fact they are NOT the same! Thank you for saving my coding-life –
Singsong 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:
Cookies are not set automatically from AJAX response (citation: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/)
Why?
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
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: *
developer.mozilla.org/en-US/docs/Web/HTTP/… –
Homeopathist xhrFields
in ajax setup or in your jquery calls. HTH. –
Every 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:
Glad if that helped even a little bit.
path=/something
and you are requesting the page /another
then the cookie will not be sent. When you request the page /something
the cookie will be sent as expected. So check the code that sets the cookie as well. –
Felisafelise 0.0.0.0:5000
and making AJAX request to localhost:5000
and thinking they are the same. In fact they are NOT the same! Thank you for saving my coding-life –
Singsong Using
xhrFields: { withCredentials:true }
as part of my jQuery ajax call was only part of the solution. I also needed to have the headers returned in the OPTIONS response from my resource:
Access-Control-Allow-Origin : http://www.wombling.com
Access-Control-Allow-Credentials : true
It was important that only one allowed "origin" was in the response header of the OPTIONS call and not "*". I achieved this by reading the origin from the request and populating it back into the response - probably circumventing the original reason for the restriction, but in my use case the security is not paramount.
I thought it worth explicitly mentioning the requirement for only one origin, as the W3C standard does allow for a space separated list -but Chrome doesn't! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB the "in practice" bit.
Put this in your init function:
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
It will work.
There are already a lot of good responses to this question, but I thought it may be helpful to clarify the case where you would expect the session cookie to be sent because the cookie domain matches, but it is not getting sent because the AJAX request is being made to a different subdomain. In this case, I have a cookie that is assigned to the *.mydomain.com domain, and I am wanting it to be included in an AJAX request to different.mydomain.com". By default, the cookie does not get sent. You do not need to disable HTTPONLY on the session cookie to resolve this issue. You only need to do what wombling suggested (https://mcmap.net/q/86860/-why-is-jquery-39-s-ajax-method-not-sending-my-session-cookie) and do the following.
1) Add the following to your ajax request.
xhrFields: { withCredentials:true }
2) Add the following to your response headers for resources in the different subdomain.
Access-Control-Allow-Origin : http://original.mydomain.com
Access-Control-Allow-Credentials : true
After trying out the other solutions and still not getting it to work, I found out what the problem was in my case. I changed contentType from "application/json" to "text/plain".
$.ajax(fullUrl, {
type: "GET",
contentType: "text/plain",
xhrFields: {
withCredentials: true
},
crossDomain: true
});
I was having this same problem and doing some checks my script was just simply not getting the sessionid cookie.
I figured out by looking at the sessionid cookie value in the browser that my framework (Django) was passing the sessionid cookie with HttpOnly as default. This meant that scripts did not have access to the sessionid value and therefore were not passing it along with requests. Kind of ridiculous that HttpOnly would be the default value when so many things use Ajax which would require access restriction.
To fix this I changed a setting (SESSION_COOKIE_HTTPONLY=False) but in other cases it may be a "HttpOnly" flag on the cookie path
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?
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
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:'/'**});
This errors occurs when you try to send cross site request. How I solve this problem?
In nginx configuration file I added
add_header Access-Control-Allow-Origin '*.domain.com'
add_header Access-Control-Allow-Credentials 'true';
And in the 'domain.com' I'm trying to send ajax request with
$.ajax({
url: sub.domain.com,
xhrFields: {
withCredentials: true
}
});
Perhaps not 100% answering the question, but i stumbled onto this thread in the hope of solving a session problem when ajax-posting a fileupload from the assetmanager of the innovastudio editor. Eventually the solution was simple: they have a flash-uploader. Disabling that (setting
var flashUpload = false;
in asset.php) and the lights started blinking again.
As these problems can be very hard to debug i found that putting something like the following in the upload handler will set you (well, me in this case) on the right track:
$sn=session_name();
error_log("session_name: $sn ");
if(isset($_GET[$sn])) error_log("session as GET param");
if(isset($_POST[$sn])) error_log("session as POST param");
if(isset($_COOKIE[$sn])) error_log("session as Cookie");
if(isset($PHPSESSID)) error_log("session as Global");
A dive into the log and I quickly spotted the missing session, where no cookie was sent.
session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();
this way, they'd get a working thing –
Middleoftheroad © 2022 - 2024 — McMap. All rights reserved.