【问题标题】:getting csrf tokens for json post requests to a rails app为 Rails 应用程序的 json 发布请求获取 csrf 令牌
【发布时间】:2012-05-11 22:20:03
【问题描述】:

我一直在尝试使用 rest-client 来访问我编写的 Rails 应用程序。我编写了一个快速脚本来登录并发出发布请求。一切正常,但我确实必须解决这样一个事实,即如果您在 json 中请求表单,则不会提供authenticity_token。我必须在其他获取authenticity_token 时发出常规的html 请求,然后将其包含在我提交的json 作为我的发布请求的一部分。基本上我有一个像下面这样的快速脏脚本

private_resource = RestClient::Resource.new( 'https://mysite.com')

params =  {:user => {:email => 'user@mysite.com', :password => 'please'}}
#log in
login_response = private_resource['users/sign_in'].post(params, :content_type => :json, :accept => :json)
#get cookie
cookie = login_response.cookies
#get json  
json_response = private_resource['products/new'].get(:content_type => :json, :accept => :json, :cookies => cookie)
#another request that returns html form with authenticity token 
response_with_token = private_resource['products/new'].get( :cookies => cookie)
#extract token 
token = Nokogiri::XML(response_with_token).css('input[name=authenticity_token]').first.attr('value')
#update cookie
cookie = response_with_token.cookies
#populate form and insert token
form = JSON.parse(json_response)
form['name'] = "my product"
form['authenticity_token'] = token
#submit the request
private_resource['products'].post(form.to_json, {:cookies => cookie, :content_type => :json, :accept => :json})

可以选择关闭对 json 请求的 CSRF 保护,但我宁愿不这样做。我可以走机械化路线或类似的路线,然后我不会担心使用 CSRF 的 json 请求,但我只是想尝试用 rest-client 做这些事情

我想我只是想知道为什么没有为 json 请求提供authentity_token 的原因,我还想知道是否有比我使用的相当老套的方法更好的解决令牌问题的方法拍到这里

【问题讨论】:

    标签: json ruby-on-rails-3.1 csrf rest-client


    【解决方案1】:

    将以下代码放入您的应用程序控制器:

    def verified_request?
        if request.content_type == "application/json"
          true
        else
          super()
        end
    end
    

    并使用 before_filter 调用此方法。

    更多详情请查看: http://blog.technopathllc.com/2011/09/rails-31-csrf-token-authenticity-for.html

    并在 rails 中检查此问题:https://github.com/rails/rails/issues/3041

    【讨论】:

    • 感谢您的回复 swati,它看起来很有用。我想虽然我试图避免关闭 CSRF 检查。对我来说,rails 提供不包含任何令牌但会检查令牌的 json 表单对我来说似乎有点奇怪。仅使用包含令牌的 json 表单而不是关闭对 json 内容的检查是否有意义?
    • 欢迎...是的,这是绕过 CSRF 令牌问题的唯一方法。如果您想通过 JSON 请求传递令牌,可以使用如下标头: headers: { 'X-CSRF-Token': '' }
    【解决方案2】:

    在您的app/views/products/new.json.jbuilder 中,添加以下内容:

    json.authenticity_token form_authenticity_token
    

    这将插入一个键"authenticity_token",其值为令牌,因此在您的json_response 中您也可以获得令牌。来自this answer的想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 1970-01-01
      • 2018-12-23
      • 2016-07-16
      • 2021-10-17
      • 2017-12-19
      • 2016-02-29
      相关资源
      最近更新 更多