MobileSafari 不会发回使用 CORS 设置的 Cookie
Posted
技术标签:
【中文标题】MobileSafari 不会发回使用 CORS 设置的 Cookie【英文标题】:MobileSafari won't send back Cookies set with CORS 【发布时间】:2012-12-21 19:21:56 【问题描述】:我在 MobileSafari 中加载了一个页面,该页面通过 CORS 与另一台服务器通信。
在桌面浏览器(经过测试的 Chrome 和 Safari)中,我能够登录,获取会话 cookie,并将该会话 cookie 发回以供后续请求,以便我可以通过所有 API 调用进行身份验证。
但是,当我通过 Mobile Safari 登录时,cookie 不会在后续请求中被发回。
我正在使用 Charles Proxy 监视正在发生的事情,它告诉我:
POST https://myremoteserver.com/sessions.json
传递我的登录信息
成功并收到带有有效Set-Cookie
标头的响应。
请求了 GET https://myremoteserver.com/checkout.json
,但没有 Cookie
请求标头。
服务器响应好像我没有登录一样。
我将这个 sn-p 与 Zepto.js
一起使用,以确保在 XHR 对象上正确设置了 withCredentials: true
。 (请原谅咖啡脚本)
# Add withCredentials:true to the xhr object to send the remote server our cookies.
xhrFactory = $.ajaxSettings.xhr
$.ajaxSettings.xhr = ->
xhr = xhrFactory.apply(this, arguments)
xhr.withCredentials = yes
xhr
而且 sn-p 在桌面浏览器中运行良好,在我添加它之前,我无法在那些桌面浏览器中保留会话 cookie。
MobileSafari 中是否有一些怪癖会阻止它像桌面浏览器一样工作?为什么它的工作方式不一样?
编辑!
这是我在 rails 2.3 应用程序中设置的 CORS 标头,我相信这是相当标准的东西
def add_cors_headers
if valid_cors_domain
headers['Access-Control-Allow-Origin'] = request.headers['HTTP_ORIGIN']
headers['Access-Control-Expose-Headers'] = 'ETag'
headers['Access-Control-Allow-Methods'] = 'GET, POST, PATCH, PUT, DELETE, OPTIONS, HEAD'
headers['Access-Control-Allow-Headers'] = '*,x-requested-with,Content-Type,If-Modified-Since,If-None-Match'
headers['Access-Control-Allow-Credentials'] = 'true'
headers['Access-Control-Max-Age'] = '86400'
end
end
今天,Mountain Lion 上的桌面 Safari 也开始不发送 cookie,其行为与 MobileSafari 类似。我不完全确定我昨天的评估是否不准确,或者 Apple 只是在欺骗我......
在远程 url 上使用 https://
也会影响这一点吗?
【问题讨论】:
您可以使用 test-cors.org 在移动 safari 上向您的服务器发送 CORS 请求吗?它在那里工作吗? @monsur 使用该工具,我可以向/sessions/new
发出获取请求,该请求应该开始一个会话。我看到 cookie 下降了,当我对同一页面发出第二次请求时,我可以看到在 Chrome 中发送回来的 cookie 标头,但在 Safari 或 MobileSafari 上的第二次请求没有发送 cookie。
A small nit: '*' 不是Access-Control-Allow-Headers
响应标头的有效值。但是,这不应该导致您看到的问题。您还可以包含失败请求的 Charles Proxy 请求/响应标头吗?
刚刚遇到以下问题;这可能是 Safari 的错误吗? ***.com/questions/14256455/…
呸,我现在似乎无法让 Charles 很好地使用 SSL,尽管我认为以前是这样。这太烦人了。
【参考方案1】:
我不知道此解决方案是否可行或您是否可以接受,但我在使用移动 Safari 和 JSONP 应用程序时遇到了同样的问题。似乎 Safari 未设置为接受第三方 cookie。我去了设置> Safari>接受Cookies并设置为“始终”,问题就消失了。祝你好运。
Can I set cookies in a response from a jsonp request?
【讨论】:
【参考方案2】:您没有提到远程服务器是在不同的域下还是只是在不同的子域下。我假设在不同的域下。
正如@schellsan 指出的那样,即使 CORS 政策允许,您也不能将 cookie 设置/写入到不同的域,因为 Safari 的 3rd 方 cookie 限制。这是最新的野生动物园限制。我猜 Firefox 也将这样做。
我目前正在评估的解决方法:
在远程服务器上使用重定向,这样当客户端被重定向时(远程URL在浏览器栏中)你可以设置cookie 使用自定义标题【讨论】:
【参考方案3】:打开一个通过 iFrame 设置 cookie 的地址 - 这将设置 cookie。
【讨论】:
【参考方案4】:我遇到了同样的问题。
我的设置是:
服务器 A 上的 AngularJS (Ionic) 应用程序,域为 a.com 以 Passport JS 作为后端的 NodeJS,位于域 b.com 的服务器 B 上除了 ios 上的 Mobile Safari 之外,每个浏览器都可以使用 cookie 登录。此外,iOS 中移动 cookie(不跟踪)设置的更改对问题没有任何影响。
解决方案是设置 CNAME DNS 记录
backend.a.com CNAME b.com
【讨论】:
您要将此记录添加到哪个域的 DNS 中?a.com
或 b.com
?【参考方案5】:
我相信您正在体验我在我的应用中看到的情况。我的问题是因为 iOS Safari 带有一个默认选项 "Prevent Cross-Site Tracking"
默认启用的,这会导致浏览器阻止所有第三方 cookie,即使是后端服务器从不同域和 CORS 发出的 cookie配置正确。
我发现这个问题的唯一解决方案是在生产中使用代理,就像我在开发中所做的那样。我在 Azure 中使用 Azure Functions 完成了这项工作,并使所有请求都通过代理。那时 iOS Safari 并没有阻止我的 cookie,一切都按预期设置。
我在我的博客https://medium.com/@omikolaj1/complete-guide-to-deploying-angular-and-asp-net-33a0976d0ec1 中写过它
【讨论】:
我可以确认,当我在 Safari(移动设备)上关闭“防止跨站点跟踪”时,每个请求都设置了 cookie。 但我不能指望我的应用程序的每个用户都禁用此设置。所以我需要另一个解决方案。所以我想问你代理服务器如何解决这个问题?因为对于 Safari(移动)浏览器,代理服务器本身就是 CORS 资源/域,因此不应在向该代理发出请求时发送 Cookie。你能解释一下吗? 我不确定我是否完全遵循,或者我可能没有所有信息。但是,当您的应用程序托管在 www.spa.com 并且您的 api 位于不同的域(例如 api.com)并且您通过 api.com/some-resource 向 api 发出请求时,您将在这个问题中遇到问题。但是,如果您要在spa.com/api/some-resource 提出请求,那么移动浏览器应该转发 cookie,因为您没有从浏览器发出任何跨源资源共享请求。然后代理服务器向 api.com 发出实际请求。 到目前为止了解。但代理服务器与 www.spa.com 托管在同一台服务器上。因为如果不是,代理服务器将具有不同的域。或不?根据我目前的研究,代理服务器通常托管在不同的独立服务器上。 啊,我明白了,是的,“代理服务器”本质上必须托管水疗中心。或者您可以使用 azure 函数来执行此操作。以上是关于MobileSafari 不会发回使用 CORS 设置的 Cookie的主要内容,如果未能解决你的问题,请参考以下文章