我一直在使用rest-client访问我编写的rails应用程序。我写了一个快速脚本来登录并发布帖子请求。一切正常,但我确实必须解决这样一个事实,即如果你在json中请求表单,则不会提供authenticity_token。我不得不在其他地方做一个普通的html请求获取authenticity_token,然后将其包含在我作为帖子请求的一部分提交的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请求提供authenticity_token而且我也想知道是否有更好的解决令牌问题的方法,而不是我真正的hacky方法在这里拍摄
答案 0 :(得分: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
中查看此问题答案 1 :(得分:1)
在app/views/products/new.json.jbuilder
中,添加以下内容:
json.authenticity_token form_authenticity_token
这将插入一个键"authenticity_token"
,其值为令牌,因此在json_response
中您也会获得令牌。来自this answer的想法。