Cookies disappear after redirect
You should use the withCredentials
option when sending your ajax request to your http://server.com and your server.com should have the Access-Control-Allow-Credentials
set to true.
Example code in Node.JS server:
var cors = require('cors');
var corsOptions = {
origin: '*',
credentials: true };
app.use(cors(corsOptions));
More on this here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
Example code in Angular.JS client
import {RequestOptions, Request, RequestMethod} from '@angular/http';
const options = new RequestOptions({
method: RequestMethod.Post,
url: 'https://google.com',
withCredentials: true
});
More on this here: https://angular.io/api/http/RequestOptions
Also check this out: https://github.com/angular/angular/issues/24283 - it looks like a particular version of Angular had problems with this flag, so unless you're using a more up-to-date version, you might need to set the header explicitly.
The reasoning of this is, unless the server explicitly tells the client "I will accept cookies (set previously on my domain) passed by another domain" - accepting the cookies would be a security issue. More here: https://en.wikipedia.org/wiki/Cross-site_request_forgery
Your description of what is happening does not seem right.
- http://server.com/login stores a cookie 'auth' and sends a redirect instruction to http://client.com/welcome
- 'auth' cookie is sent to http://client.com/welcome
That is not (or at least should not be) what is happening. When the browser requests http://server.com/login and gets back in the response a Set-Cookie
header, the cookie is set on and restricted to the server.com
domain, even if the response is a redirect. If you are seeing the 'auth' cookie sent to client.com
then that is a cookie that client.com
previously set.
Anyway, it seems that what you really care about is
- http://client.com/welcome makes an AJAX request to http://server.com/data (CORS enabled), but the cookie 'auth' is not sent
There are a bunch of reasons this can happen.
- CORS. You mentioned it was CORS enabled, but for the sake of others reading this, you must have the following CORS headers set on
server.com
Access-Control-Allow-Origin: http://client.com
Access-Control-Allow-Credentials: true
- Note that you cannot get away with using a wildcard for
Access-Control-Allow-Origin
when you are sending credentials. Also note that the origin has to be an exact match, including scheme (http or https). In practice, what servers generally do is read theOrigin
header of the request, check it against a white list, and if it allowed, copy theOrigin
header value from the request to theAccess-Control-Allow-Origin
header in the response. - You must set
xhr.withCredentials = true
in your XHR request. (See MDN for more details.)
Then after you have done all that, you have one other hurdle in your way. Because you are on client.com
and trying to send a cookie to server.com
, the server.com
cookie is considered a "third-party" cookie. AFAIK all the major browsers have a setting that blocks third-party cookies for privacy, because they are most often used by trackers to gather marketing data for advertising. I believe most of them block third-party cookies by default, but I am not sure of that. For sure lots of people have set their browsers to block third-party cookies.
So you have to tell your visitors to configure their browser to allow third-party cookies from server.com
.
BTW, it is not safe to set a cookie on a redirect to a different domain. While it is allowed under the specification AFAIK, there have been issues with browser support. See, for example, this Chrome bug.