我有:
1)拥有自己域的客户端应用:http://client.com
2)具有单独域的服务器端应用程序:http://server.com
现在
情况是:
1)在浏览器中打开http://client.com/home,显示HTML页面。
2)http://client.com/home重定向到http://server.com/login
3)http://server.com/login存储cookie'auth'并将重定向指令发送到http://client.com/welcome
响应:
访问控制允许来源:*
连接:保持活动状态
内容长度:104
Content-Type:文本/ html; charset = utf-8
日期:2019年1月16日星期三10:47:11 GMT
Set-Cookie:auth = 1479da80-197c-11e9-ba74-59606594e2fb;路径= /
变化:接受
X-Powered-By:Express
4)浏览器收到响应,该响应确实包含cookie'auth'
5)浏览器将自身重定向到http://client.com/welcome
6)'auth'cookie发送到http://client.com/welcome
请求:
Cookie:auth = 1479da80-197c-11e9-ba74-59606594e2fb
7)http://client.com/welcome返回HTML,但不返回cookie“ auth”
8)http://client.com/welcome向http://server.com/data发出AJAX请求(已启用CORS),但未发送cookie'auth'
9)http://server.com/data无法识别用户,因为没有cookie
客户端是由Node.js托管的有角度的应用程序
编辑:
按照建议,我已经添加到server.com的响应中:
Access-Control-Allow-Credentials:true
但没有任何改变。
相关的客户端代码:
const headerOptions = new HttpHeaders({
'Content-Type': 'application/json', 'withCredentials': 'true', 'Access-Control-Allow-Origin': 'true', 'Access-Control-Allow-Credentials': 'true'
});
this.httpClient.get<any>(this.baseUrl + "data", { headers: headerOptions }).subscribe((res) => {
答案 0 :(得分:3)
将ajax请求发送到http://server.com时,应使用withCredentials
选项,并且server.com的Access-Control-Allow-Credentials
应当设置为true。
Example code in Node.JS server:
var cors = require('cors');
var corsOptions = {
origin: '*',
credentials: true };
app.use(cors(corsOptions));
此处的更多信息: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
});
此处的更多信息:https://angular.io/api/http/RequestOptions
也请查看:https://github.com/angular/angular/issues/24283-特定版本的Angular似乎对此标志存在问题,因此,除非您使用的是最新版本,您可能需要显式设置标题。
这样做的原因是,除非服务器明确告知客户端“我将接受另一个域传递的cookie(先前在我的域中设置)” -接受cookie将会是安全问题。更多信息,在这里:https://en.wikipedia.org/wiki/Cross-site_request_forgery
答案 1 :(得分:1)
您对正在发生的事情的描述似乎不正确。
这不是(或至少不应是)正在发生的事情。当浏览器请求http://server.com/login并在响应中返回Set-Cookie
标头时,即使响应是重定向,cookie也被设置为打开并限制在server.com
域中。如果您看到发送到client.com
的'auth'cookie,那么这是client.com
先前设置的cookie。
无论如何,看来您真正关心的是
发生这种情况的原因有很多。
server.com
上设置以下CORS标头
Access-Control-Allow-Origin: http://client.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin
使用通配符。还要注意,原点必须是完全匹配的,包括方案(http或https)。实际上,服务器通常要做的是读取请求的Origin
标头,对照白名单进行检查,如果允许,则将Origin
标头值从请求复制到{{1} }标题中。Access-Control-Allow-Origin
。 (有关更多详细信息,请参见MDN。)然后,在完成所有这些操作之后,您便会遇到另一个障碍。因为您在xhr.withCredentials = true
上并试图将cookie发送到client.com
,所以server.com
cookie被视为“第三方” cookie。 AFAIK所有主要的浏览器都有一个设置,可以阻止第三方Cookie的隐私,因为跟踪器最常使用它们来收集广告的营销数据。我相信大多数默认情况下都会阻止第三方Cookie,但是我不确定。当然,很多人都将其浏览器设置为阻止第三方Cookie。
因此,您必须告诉访问者将其浏览器配置为允许来自server.com
的第三方cookie。
顺便说一句,在重定向到其他域时设置cookie是不安全的。虽然规范AFAIK允许使用,但浏览器支持存在问题。例如,请参见此Chrome bug。
答案 2 :(得分:0)
根据“访问控制允许来源”规范: 对于没有凭据的请求,可以将字面值“ ”指定为通配符; *
尝试将特定域添加到Access-Control-Allow-Origin
字段。
我认为您应该在有角度的角度应用中使用代理。有关更多信息,请检查以下链接:https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md