如果用户未经授权,如何使用Devise发送CORS头(401响应)

我正在开发一个应用程序,其中服务器和api消费客户端位于不同的域下,所以我想使用CORS 。 为此,我必须在服务器响应中设置相应的http标头:

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

对于某些资源,用户必须经过身份validation和授权。 请求通过XHR / Ajax完成。 因此,如果用户未经过身份validation, Devise将向客户端发送401响应,而不是重定向到登录页面。 但是用于设置CORS头的filter不用于该响应。 因此,401响应不会发送给客户端。 我想在客户端捕获并使用401响应。

目前我使用的解决方法是不使用Devise身份validation方法,而是使用自定义身份validation代码段:

 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 

这也被设置为ApplicationControllerbefore_filter 。 这样,设置CORS标头的filter就会被触发,一切正常。

我更喜欢使用Devise的默认行为,但必须在401响应中设置CORS头。 这该怎么做? 我必须为此配置监护人吗?

如何为Devise生成的401响应设置CORS头,而不是创建自己的响应?

我成功地使用了rack-cors gem https://github.com/cyu/rack-cors,并在我的博客上概述了我的经验。

Punchline:指定中间件订单,因此cors处理程序在warden之前:

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

我们通常不喜欢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