ruby-on-rails - 为什么没有在 XHR 请求上设置设计 cookie?

标签 ruby-on-rails cookies devise xmlhttprequest ruby-on-rails-4

我在提供 JSON API 的 Rails4 应用程序上使用设计。我修补了设计,因此它通过 HTTP header 而不是 URL 参数接受身份验证 token 。这很好用。

基于该 API 的 JS 单页应用程序运行良好。我可以对用户进行身份验证,并在应用程序内请求此用户资源。

此外,我希望服务器(设计)设置一个 cookie,以便基于 cookie 的身份验证工作,并且我也可以通过非 XHR 请求请求用户私有(private)资源。这不起作用,我不知道为什么。

我有我的设计初始化程序:

config.http_authenticatable_on_xhr = true

在我的 session_store 初始化程序中,我设置了:
MyApp::Application.config.session_store :cookie_store, key: '_myapp_session', domain: :all, httponly: false, secure: false

当我在 Chrome 中运行我的单页应用程序并检查网络请求时,我可以看到对服务器端资源请求的每个响应都包含一个 Set-Cookie像这样的标题:
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Ua-Compatible: chrome=1
Access-Control-Allow-Origin: * //dont give me shelter
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS, DELETE
Access-Control-Max-Age: 1728000
X-Meta-Request-Version: 0.2.8
Etag: "7b64cd327b9ff8dce6bb8b616aeee2b8"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 1d6be45e-ce45-40fd-b03b-358644826955
X-Runtime: 0.283514
Server: WEBrick/1.3.1 (Ruby/2.0.0/2013-06-27)
Date: Fri, 23 Aug 2013 10:36:04 GMT
Connection: Keep-Alive
Set-Cookie: _myapp_session=NndJcUd5QUJmRktkSkdTVTk1NTF3UHVKaW85QkVmTmpqZEM4Q3BqUW5ORzNyNG5HWmlnSWc5Yy83Nk16c3Q0dk1iVXQ0Q2JqTE1qZWZoaDgxNW1RQnErOHhsVG9rdEQ4cU1CNGsyNWsrVlk0OXlLRGo5c1BiN3NkdFlRdWJHVXBDamI1U1BrdlQ3Mmw3OWNZVWJkWGI1UWZqNDJ1VldxL0xvYkkwYVd5aHBYaU5sOElkZ3NSRXZVdGxlWHQxY1FteFh1OGU3NHowYU0xYTRLK2xuTEN4KzhzR2pjR25YWlZVSTZtZDkvUnZXbz0tLXJKMXNlV1gvcHFuaG5jU3YvNUJhSnc9PQ%3D%3D--5ecf40e2a678b467b77aa0c56494be8e079641d2; domain=.myapp.dev; path=/

我的应用程序来自 app.myapp.dev在端口 9000 上并在 api.myapp.dev 处请求 API在端口 3000 上。由于正确的 CORS 配置,这可以正常工作。

如果我在 Cookies 下查看 Chrome 的资源面板没有设置 cookie。由于没有 cookie,对 api.myapp.net 的每个非 XHR 请求都不会对用户进行身份验证。

我不明白,为什么 cookie 设置的 header 看起来很好,但 cookie 没有设置?

任何人都可以启发我吗?

问候
菲利克斯

最佳答案

好的,到目前为止我发现,可以从 a.domain.com 交付一个 JS 应用程序。并让它从 b.domain.com 获取 JSON 数据启用了 CORS,但 cookie 由 b.domain.com 发送不会设置。某种邪恶可能会在这里发生。

所以在我的情况下解决问题的唯一方法是:让用户登录到 JS 应用程序,将他重定向到 b.domain.com 的端点。并添加一个身份验证 token 。位于 b 的服务器登录用户,现在可以设置 cookie 并将用户重定向到 JS 应用程序。

这是一个可怕的解决方案,导致应用程序加载两次,但只要您从另一个子域而不是您的 API 交付您的应用程序,似乎没有更好的解决方案。对任何人都非常开放。

更新

如果您可以控制服务器 header ,则确实可以设置跨域 cookie。

在我的案例中解决问题的是:
b.domain.com设置一个额外的响应头 Access-Control-Allow-Credentials为真。此外, Backbone 同步内部需要修补,以便传递的选项对象获得 key xhrFieldswithCredentials:true .就是这样。当b.domain.com回复 Set-Cookie header ,cookie 已设置,即使 JS 应用程序是从 a.domain.com 交付的.不要忘记:当您设置 Access-Control-Allow-Credentials 时,您不能对 Access-Control-Allow-Origin 使用通配符(无论如何您都不应该这样做)。

关于ruby-on-rails - 为什么没有在 XHR 请求上设置设计 cookie?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18400980/

相关文章:

ruby-on-rails - 如何在 rails 4 中渲染 .js.erb 文件的部分内容?

javascript - 小 map 网站导航

ruby-on-rails - rails : sign out logged in user on event

ruby-on-rails - 设计 - 快速通知

ruby-on-rails - Rails 3迁移:(非主键)列上的自动增量?

ruby-on-rails - 解析来自 Google 大查询的响应

javascript - 登录可以在 Chrome 和 Firefox 上使用,但不能在 Edge 上使用

javascript - 照片库 css 选定状态未被 cookie 读取

ruby-on-rails - 设计密码重置链接不适用于 https

compilation - 警告 : Nokogiri was built against LibXML version 2. 7.7,但已动态加载 2.6.16