8

我一直在尝试使用 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 的原因,我还想知道是否有比我在这里采取的相当老套的方法更好的解决令牌问题的方法

4

2 回答 2

8

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

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

于 2012-05-02T13:01:33.870 回答
2

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

json.authenticity_token form_authenticity_token

这将插入一个"authenticity_token"值为令牌的键,因此您json_response也将获得令牌。来自这个答案的想法。

于 2016-08-28T01:25:49.620 回答