2013-01-08 89 views
33

试图实施ajax登录/注册过程(无需身份验证的刷新站点)。使用Cookie保存状态。我认为我现在有这个权利,但由于某种原因,浏览器在从服务器获取它们之后不会设置cookie。谁能帮忙?下面是请求和响应头:通过CORS的Ajax请求在浏览器上设置Cookie

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

请求头

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"} 

响应头

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 

我也看到在Chrome网络工具的cookie,从返回服务器:

响应cookie

Name: site 
Value: %2B1THQQ%2BbZkEwTYFvXFVV5fxi00l2K%2B6fvt9SuHACTNsEwUGzDSUckt38ZeDsNbZSsqzHmPMWRLc84eDLZzh8%2Fw%3D%3D 
Domain: .site.dev 
Path:/
Expires: Session 
Size: 196 
Http: ✓ 
+0

这是根据RFC2109第4.3.2节的域匹配问题?我并不完全清楚您的主机(api.site.dev)和cookie域(.site.dev)是否根据需要“域匹配”。 CORS方面并没有使这个更容易演绎:) – broofa

+0

[CORS请求 - 为什么cookie没有发送?](http://stackoverflow.com/questions/8863571/cors-request - 为什么是cookies没有发送) –

回答

17

你的AJAX请求必须设置为true的“withCredentials”设置(仅XMLHttpRequest2中使用和提取)进行:

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; 

如果您想对CORS,API安全,和饼干的详细说明,答案不适合StackOverflow评论。看看这篇文章,我写了关于这个问题:http://www.redotheweb.com/2015/11/09/api-security.html

+1

问题: - 当凭证标志为真时,'Access-Control-Allow-Origin'标头中不能使用通配符'*'。因此不允许原产地'null'访问。 – ZiglioUK

+0

弗朗索瓦,我读过你的文章,我正在使用一个api,这是一个web服务。它需要系统认证(不是由数据库驱动)。我使用的凭据和能够登录。现在可以将此凭据存储在Cookie中并绕过验证。感谢文章。 –

+0

您还必须将响应头“Access-Control-Allow-Credentials”设置为“true”,否则浏览器将阻止(拒绝)请求。 – Tim

5

我有一个类似的问题,它原来的浏览器设置被阻断第三方Cookie(Chrome浏览器>设置>高级设置>隐私设置>内容设置>阻止第三方Cookie和网站数据)。解除封锁解决了问题!

+2

确实。由于这是Safari中的默认设置,并且在大多数其他浏览器中可能,因此制作网站(通过CORS依赖于第三方Cookie)应该考虑一些问题。很少有用户可能会被告知为网站启用第三方Cookie。 –

+0

我刚刚花了三个小时进行故障排除并寻找支持,然后才意识到这是我的问题。谢谢! – Chris

+11

我遇到同样的问题,但“阻止第三方Cookie和网站数据”已被禁用。 – Thayne