Pau*_*aul 126 ruby-on-rails csrf protect-from-forgery angularjs
如果protect_from_forgery在application_controller中提到了该选项,那么我可以登录并执行任何GET请求,但是在第一次POST请求时,Rails会重置会话,这会导致我退出.
我protect_from_forgery暂时关闭了该选项,但想将它与Angular.js一起使用.有办法做到这一点吗?
小智 274
我认为从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标头
以下是基于这些说明的解决方案:
首先,设置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
Run Code Online (Sandbox Code Playgroud)
然后,我们应该在每个非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
Run Code Online (Sandbox Code Playgroud)
Mic*_*ley 78
如果您使用的是默认的Rails CSRF保护(<%= csrf_meta_tags %>),则可以像下面这样配置Angular模块:
myAngularApp.config ["$httpProvider", ($httpProvider) ->
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
]
Run Code Online (Sandbox Code Playgroud)
或者,如果你没有使用CoffeeScript(什么!?):
myAngularApp.config([
"$httpProvider", function($httpProvider) {
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
}
]);
Run Code Online (Sandbox Code Playgroud)
如果您愿意,可以仅在非GET请求上发送标头,如下所示:
myAngularApp.config ["$httpProvider", ($httpProvider) ->
csrfToken = $('meta[name=csrf-token]').attr('content')
$httpProvider.defaults.headers.post['X-CSRF-Token'] = csrfToken
$httpProvider.defaults.headers.put['X-CSRF-Token'] = csrfToken
$httpProvider.defaults.headers.patch['X-CSRF-Token'] = csrfToken
$httpProvider.defaults.headers.delete['X-CSRF-Token'] = csrfToken
]
Run Code Online (Sandbox Code Playgroud)
另外,请务必查看HungYuHei的答案,其中涵盖了服务器上的所有基础,而不是客户端.
小智 29
该angular_rails_csrf宝石会自动为所描述的模式支持HungYuHei的回答您的所有控制器:
# Gemfile
gem 'angular_rails_csrf'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45835 次 |
| 最近记录: |