通配符 CORS 与 allowcredentials true
Posted
技术标签:
【中文标题】通配符 CORS 与 allowcredentials true【英文标题】:Wildcard CORS with allowcredentials true 【发布时间】:2014-08-23 06:55:14 【问题描述】:我有一个项目使用通配符子域,例如 user.mysite.com
,其中用户名是通配符。
在我的服务器 (php) 中,我设置了以下标头:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials: true');
这允许我从前端进行 ajax 调用,因为我不知道域将是什么。但是,我还需要将我的 cookie 与维护会话的请求一起发送,但是当我在前端告诉 AngularJS 发送凭据时,我收到以下消息:
A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true
我知道这是出于安全原因,但现在我无法在我的应用中进行会话管理。任何人都可以为此提出解决方法吗?
我告诉 Angular 发送凭据的地方:
$httpProvider.defaults.withCredentials = true;
我的 ajax 请求被发送到不同的子域。即 url 可以是billy.mysite.com
,但是 ajax 请求被发送到api.mysite.com
。
【问题讨论】:
只需获取当前请求的主机并使用它而不是通配符 我怎么没想到?!谢谢@PeeHaa 【参考方案1】:PeeHaa 在 cmets 中是正确的:
只需获取当前请求的主机并使用它而不是通配符
也就是说,执行以下操作:
header('Access-Control-Allow-Origin: '.$requestHeaders['Host']);
别这样!
这正是您所要求的,它解决了问题。基本上相当于header('Access-Control-Allow-Origin: *');
但是,这会造成巨大的安全漏洞。
这样做实际上意味着您的用户进入的任何站点都可以在未经用户同意或通知的情况下代表您的用户执行任何操作,因为您将 Access-Control-Allow-Origin
转发给发送的任何主机和允许此主机传输原始用户的 cookie(如果在浏览器中为您的 API 设置了它)。
相反,在中继之前,您应该始终过滤主机。实施某种白名单检查或正则表达式检查,仅当通过时,将Host
中继到Access-Control-Allow-Origin
。
【讨论】:
HOST 就不能被欺骗吗? 如果你已经有了cookie,你当然可以欺骗HOST或者只是把cookie放在你的浏览器中。但是,如果您按照建议执行 CORS,则可以欺骗用户访问恶意站点以冒充他。用户没有在那里输入他们的登录信息,甚至根本不知道该站点做了任何事情。任何时候都不需要窃取 cookie。【参考方案2】:@iamjonesy - 你犯了一个愚蠢的错误。
"A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true"
为避免上述错误,请按照以下步骤操作。 假设您的 api 服务器是 http://api.com 。而您执行 ajax 调用的 UI 服务器是 http://ui.com
PHP头代码应该是这样的,
header('Access-Control-Allow-Origin: http://ui.com');
header('Access-Control-Allow-Credentials: true');
将下面的行放入 angular config.js
$httpProvider.defaults.withCredentials = true;
我所做的,从未将“*”设置为 $httpProvider.defaults.withCredentials 的通配符,只需提及 ajax 代码所在位置的完整域名即可。
【讨论】:
我们有一个 servicestack 服务器(带有一个已知端点)和多个带有未知端点的 UI 服务器。我们希望 UI 服务器用户能够通过写入 cookie 对 servicestack 服务进行身份验证。我认为添加 withCredentials 允许这样做 但是 servicestack 服务器如何允许未知 UI 访问 JSON 服务响应? @CoreyAlix 我正在寻找解决同一问题的方法。我们如何允许未知域这样做?如果您找到解决方案,请在此处发布。 @dev_musings 我切换到 JSONP。 @dev-musings,JSONP 不是答案,因为我们的服务不都是 GET 服务。我们不得不引入应用服务器白名单。我认为没有解决方法。 @CoreyAlix 出于安全考虑,现代浏览器拒绝来自未知/未经身份验证端点的响应。使用 JSONP 不是解决方案,因为它仅支持 GET 方法。您可以做的一件事是构建您的 API,在其中可以通过任何开源命令行工具和库 (CURL/urllib2) 访问这些未知端点。我想它可能会对你有所帮助。以上是关于通配符 CORS 与 allowcredentials true的主要内容,如果未能解决你的问题,请参考以下文章
AWS Api Gateway CORS“访问控制允许来源”正则表达式与 Cloudformation