如果protect_from_forgery在application_controller中提到了该选项,那么我可以登录并执行任何GET请求,但是在第一个POST请求上,Rails重置了会话,这使我注销。
protect_from_forgery
我protect_from_forgery暂时关闭了该选项,但希望将其与Angular.js一起使用。有什么办法吗?
我认为从DOM读取CSRF值不是一个好的解决方案,这只是一种解决方法。
这是angularJS官方网站http://docs.angularjs.org/api/ng.$http的文档格式 :
由于只有在您的域上运行的JavaScript才能读取Cookie,因此可以确保您的服务器XHR来自在您的域上运行的JavaScript。 要利用此优势(CSRF保护),您的服务器需要在第一个HTTP GET请求上的名为XSRF- TOKEN的JavaScript可读会话cookie中设置令牌。在后续的非GET请求上,服务器可以验证Cookie是否与X-XSRF-TOKEN HTTP标头匹配
由于只有在您的域上运行的JavaScript才能读取Cookie,因此可以确保您的服务器XHR来自在您的域上运行的JavaScript。
要利用此优势(CSRF保护),您的服务器需要在第一个HTTP GET请求上的名为XSRF- TOKEN的JavaScript可读会话cookie中设置令牌。在后续的非GET请求上,服务器可以验证Cookie是否与X-XSRF-TOKEN HTTP标头匹配
这是基于这些说明的我的解决方案:
首先,设置cookie:
# app/controllers/application_controller.rb # Turn on request forgery protection protect_from_forgery after_action :set_csrf_cookie def set_csrf_cookie cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery? end
然后,我们应该在每个非GET请求上验证令牌。 由于Rails已经使用类似的方法构建,因此我们可以简单地重写它以附加我们的逻辑:
# app/controllers/application_controller.rb protected # In Rails 4.2 and above def verified_request? super || valid_authenticity_token?(session, request.headers['X-XSRF-TOKEN']) end # In Rails 4.1 and below def verified_request? super || form_authenticity_token == request.headers['X-XSRF-TOKEN'] end