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.comb.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的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4 登录凭据不匹配不会发回错误数据

Nginx Web 浏览器 CORS 问题

我怎样才能修复这个承诺,这样我就不会发回未定义的

API GW Lambda 代理集成 CORS 问题

移动 Safari - 输入插入符号不会随着溢出滚动一起滚动:触摸

为啥我的 Mobile Safari 缓存不会清除?