获取csrf令牌以获取json发布请求到rails应用程序

时间:2012-05-02 12:31:21

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

我一直在使用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方法在这里拍摄

2 个答案:

答案 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

并在rails:https://github.com/rails/rails/issues/3041

中查看此问题

答案 1 :(得分:1)

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

json.authenticity_token form_authenticity_token

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