3

我在提供JSON API的Rails4应用程序上使用devise。我修补了设计,因此它通过HTTP标头而不是URL参数接受认证令牌。这工作得很好。为什么在XHR请求中未设置设计cookie?

基于该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,每个非XHR对api.myapp.net的请求都不会对用户进行身份验证。

我不明白,为什么cookie集头看起来不错,但cookie没有设置?

任何人都可以启发我吗?

问候 菲利克斯

回答

2

好了,因为我发现至今,它可以从a.domain.com提供一个JS应用程序,让它从b.domain.com获取JSON数据启用CORS,但b.domain.com发送的cookie不会组。某种邪恶可能会在这里发生。

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

这是一个可怕的解决方案,导致该应用程序加载两次,但只要你从另一个子域提供你的应用程序比你的API似乎没有更好的解决方案。相当开放的任何。

更新

设置跨域饼干确实有可能的情况下,你是在服务器头的控制。

什么解决了我的情况,问题是:

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