【问题标题】:Why is a devise cookie not set on XHR request?为什么没有在 XHR 请求上设置设计 cookie?
【发布时间】:2013-08-26 09:30:06
【问题描述】:

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

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

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

我有我的设计初始化器:

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=/

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

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

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

谁能赐教?

问候 费利克斯

【问题讨论】:

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


    【解决方案1】:

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

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

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

    更新

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

    在我的案例中解决问题的是:

    b.domain.com 将额外的响应头 Access-Control-Allow-Credentials 设置为 true。此外,需要修补主干同步内部,以便传递的选项对象获得密钥xhrFieldswithCredentials:true。就是这样。当b.domain.com 响应Set-Cookie 标头时,cookie 被设置,即使JS 应用程序是从a.domain.com 交付的。不要忘记:当您设置 Access-Control-Allow-Credentials 时,您不能对 Access-Control-Allow-Origin 使用通配符(无论如何都不应该这样做)。

    【讨论】:

      猜你喜欢
      • 2012-02-21
      • 1970-01-01
      • 2020-12-05
      • 2011-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多