Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set-Cookie on Browser with Ajax Request via CORS

Attempting to implement an ajax login / signup process (no refresh site with authentication). Using cookies for preserving state. I thought I'd have this right by now but for some reason browser doesn't set cookies after it gets them back from the server. Can anyone help? Here are the request and response headers:

Request URL:http://api.site.dev/v1/login Request Method:POST Status Code:200 OK 

Request Headers

Accept:application/json, text/plain, */* Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8 Connection:keep-alive Content-Length:57 Content-Type:application/json;charset=UTF-8 Host:api.site.dev Origin:http://site.dev Referer:http://site.dev/ User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.101 Safari/537.11 withCredentials:true X-Requested-With:XMLHttpRequest Request Payload {"email":"[email protected]","password":"foobar"} 

Response Headers

Access-Control-Allow-Credentials:true Access-Control-Allow-Headers:X-Requested-With, Content-Type, withCredentials Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Origin:http://site.dev Connection:Keep-Alive Content-Length:19 Content-Type:application/json Date:Tue, 08 Jan 2013 18:23:14 GMT Keep-Alive:timeout=5, max=99 Server:Apache/2.2.22 (Unix) DAV/2 PHP/5.4.7 mod_ssl/2.2.22 OpenSSL/0.9.8r Set-Cookie:site=%2B1THQQ%2BbZkEwTYFvXFVV5fxi00l2K%2B6fvt9SuHACTNsEwUGzDSUckt38ZeDsNbZSsqzHmPMWRLc84eDLZzh8%2Fw%3D%3D; expires=Thu, 10-Jan-2013 18:23:14 GMT; path=/; domain=.site.dev; httponly X-Powered-By:PHP/5.4.7 

I also see the cookie in chrome network tools, as returned from the server:

Response Cookies

Name: site Value: %2B1THQQ%2BbZkEwTYFvXFVV5fxi00l2K%2B6fvt9SuHACTNsEwUGzDSUckt38ZeDsNbZSsqzHmPMWRLc84eDLZzh8%2Fw%3D%3D Domain: .site.dev Path: / Expires: Session Size: 196 Http: ✓ 
like image 201
Calvin Froedge Avatar asked Jan 08 '13 18:01

Calvin Froedge


People also ask

Can I set cookie on AJAX request?

Yes, you can set cookie in the AJAX request in the server-side code just as you'd do for a normal request since the server cannot differentiate between a normal request or an AJAX request.

Does AJAX need CORS?

When building complex client-side applications, at some point it usually becomes necessary to make Ajax requests to domains other than the one from which your page originated. This is especially true if you are part of a large enterprise with distributed sub-domained resources.

Can you set cookie in GET request?

Also I would say it is perfectly acceptable to change or set a cookie in response for the GET request because you just return some data.


2 Answers

Your AJAX request must be made with the "withCredentials" settings set to true (only available in XmlHttpRequest2 and fetch):

    var req = new XMLHttpRequest();     req.open('GET', 'https://api.bobank.com/accounts', true); // force XMLHttpRequest2     req.setRequestHeader('Content-Type', 'application/json; charset=utf-8');     req.setRequestHeader('Accept', 'application/json');     req.withCredentials = true; // pass along cookies     req.onload = function()  {         // store token and redirect         let json;         try {             json = JSON.parse(req.responseText);         } catch (error) {             return reject(error);         }         resolve(json);     };     req.onerror = reject; 

If you want a detailed explanation on CORS, API security, and cookies, the answer doesn't fit in a StackOverflow comment. Check out this article I wrote on the subject: http://www.redotheweb.com/2015/11/09/api-security.html

like image 88
François Zaninotto Avatar answered Sep 23 '22 15:09

François Zaninotto


I had a similiar problem, and it turned out that the browser settings were blocking third-party cookies (Chrome > Settings > Advanced Settings > Privacy > Content Settings > Block third-party cookies and site data). Unblocking solved the problem!

like image 37
Andrew M. Andrews III Avatar answered Sep 23 '22 15:09

Andrew M. Andrews III