2012-06-24 34 views
18

我正在研究一個應用程序,其中服務器和api消費客戶端位於不同的域下,所以我想使用CORS。要做到這一點,我已經在服務器響應以設置相應的HTTP標頭:如果用戶未經授權,如何發送CORS頭文件(401響應)

def cors_set_access_control_headers 
    headers['Access-Control-Allow-Origin'] = 'http://localhost' 
    headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS' 
    headers['Access-Control-Allow-Headers'] = '*, X-Requested-With, X-Prototype-Version, X-CSRF-Token, Content-Type' 
    headers['Access-Control-Max-Age'] = "1728000" 
end 

該方法被用作一個ApplicationControllerbefore_filter

對於一些資源,用戶必須經過認證和授權。請求通過XHR/Ajax完成。因此,如果用戶未通過認證,Devise將向客戶端發送401響應,而不是重定向到登錄頁面。但是用於設置CORS頭的過濾器不用於該響應。因此401響應不會發送給客戶端。我想在客戶端捕獲並使用401響應。

目前我使用一種變通方法不使用的設計驗證方法,但是自定義AUTH片段:

def authenticate_cors_user 
    if request.xhr? && !user_signed_in? 
    error = { :error => "You must be logged in." } 
    render params[:format].to_sym => error, :status => 401 
    end 
end 

這被設置爲ApplicationController一個before_filter了。通過這種方式,設置CORS頭部的過濾器被觸發並且一切正常。

我寧願使用Devise的默認行爲,但CORS頭將不得不在401響應中設置。這個怎麼做?我必須爲此配置warden嗎?

如何爲Devise生成的401響應設置CORS頭,而不是創建自己的響應?

+0

可是我還是不有專門的解決方案。爲了提供更多的上下文,請查看我的博客文章,瞭解我如何使用此功能:http://nils-blum-oeste.net/cors-api-with-oauth2-authentication-using-rails-and-angularjs –

回答

21

我成功地使用機架-CORS寶石https://github.com/cyu/rack-cors,並概述了my blog我的經驗。

警句:指定中間件爲了使CORS處理程序是監獄長前:

config.middleware.insert_before Warden::Manager, Rack::Cors 
+0

你的方法很好,謝謝!然而,奇怪的是,花了一些時間和一些額外的研究才知道,我真的必須在配置中只更改一行代碼,以使'Devise'和'rack-cors'能夠一起工作。 –

+0

嘿@ digger69。您是否遇到其他例外問題?例如:如果我在我的action中定義了一個異常'def index;提出'錯誤'; end' - Rails不會返回CORS頭文件(rack-cors)。對你起作用嗎? –

+4

PS:你也可以使用'config.middleware.insert 0,Rack :: Cors'來保證在任何其他可能的中間件之前插入'Rack :: Cors'。 –

0

我們通常不喜歡CORS標題。我們更喜歡使用HAProxy來重定向。

通過HAProxy,您可以設置所有來自website.com/api/的請求,以便在內部重定向到您的rails機器。

frontend main *:80 
    acl api  path_beg -i /api 
    acl app  path_beg -i /app 
backend app_backend 
    reqrep ^([^\ ]*)\ /app/(.*) \1\ /\2 
    balance roundrobin 
    server app_files smartphoneapp.localhost:8000 
backend api_backend 
    reqrep ^([^\ ]*)\ /api/(.*) \1\ /\2 
    balance roundrobin 
    server app_api localhost:3000 
+0

CORS可以當然可以用代理來規避。但是,我想,仍然必須有一種方法可以很好地處理Devise/warden。 –

+0

看看這篇文章: http://www.tsheffler.com/blog/?p=428 – Hendrik

相關問題