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(你不應該這樣做)。