asg*_*eo1 5 ajax ruby-on-rails devise cors
我有一个单页面应用程序,使用CORS对另一个域进行身份验证.所有请求都是JSON请求.
我的应用程序可以验证确定,可以使GET请求正常.身份验证使用token_authenticatable.即所有请求附加'?auth_token = whatever'
所以,我的实际问题是,当我尝试执行PUT请求时,我得到一个警告:无法在rails日志中验证CSRF令牌真实性消息以及CanCan :: AccessDenied(您无权访问此页面. )例外.
只需添加skip_before_filter :verify_authenticity_token到rails控制器即可解决问题.
因此,我只能得出结论,我的ajax请求发送的是无效或空的csrf_token.
我真的不明白它是怎么回事,因为我相信我正确地发送了每个ajax请求的X-CSRF-Token报头.
基本上,我的应用程序验证并且Devise发送回auth_token和csrf_token:
render :status => 200, :json => {
:auth_token => @user.authentication_token,
:csrf_token => form_authenticity_token
}
Run Code Online (Sandbox Code Playgroud)
然后我将这些令牌存储在我的ajax应用程序中,并ajaxSend在jQuery中使用,设置它以便jQuery为每个请求传递这些令牌:
initialize: ->
@bindTo $(document), 'ajaxSend', @appendTokensToRequest
appendTokensToRequest: (event, jqXHR, options) ->
if not @authToken? then return
if @csrfToken?
jqXHR.setRequestHeader 'X-CSRF-Token', @csrfToken
if options.type is 'POST'
options.data = options.data + (if options.data.match(/\=/) then '&' else '') +
$.param auth_token:@authToken
else
options.url = options.url + (if options.url.match(/\?/) then '&' else '?') +
$.param auth_token:@authToken
Run Code Online (Sandbox Code Playgroud)
然后,我可以在chrome网络选项卡中看到,每个GET请求auth_token都会发送param,以及X-CSRF-Token标头.
然而,在PUT请求它似乎没有工作.
我的理论是CORS正在填补空白.如果您发出CORS请求,您的浏览器实际上会首先发出一个额外的 OPTIONS请求,以检查您是否有权访问此资源.
我怀疑OPTIONS请求没有传递X-CSRF-Token头,因此rails立即使rails端的csrf_token无效.然后,当jQuery发出实际的PUT请求时,它传递的csrf_token不再有效.
这可能是问题吗?
我该怎么做才能证明这一点?Chrome似乎没有向我显示网络标签中的OPTIONS请求,以帮助我调试问题.
这不是一个重大问题,因为我可以关闭CSRF.但我想知道它为什么不起作用.
在 Rails 中,每个表单提交都需要 CSRF 令牌的真实性。它用于安全地提交表单。当我们打开应用程序时,CSRF 令牌(每次)将在 Rails 中新创建。如果 CSRF 令牌未在我们的控制器内传递,则会显示此警告。我们需要在所有表单提交中传递此令牌。
| 归档时间: |
|
| 查看次数: |
4494 次 |
| 最近记录: |