由于某种原因,在使用json或xml时向我的应用发送请求时,我收到一个InvalidAuthenticityToken.我的理解是,rails应该只需要html或js请求的真实性令牌,因此我不应该遇到这个错误.迄今为止我发现的唯一解决方案是禁用protect_from_forgery,以便我想通过API访问任何操作,但由于明显的原因,这不是理想的.思考?
def create respond_to do |format| format.html format.json{ render :json => Object.create(:user => @current_user,:foo => params[:foo],:bar => params[:bar]) } format.xml{ render :xml => Object.create(:user => @current_user,:bar => params[:bar]) } end end
这是我在通过对动作的请求时得到的日志:
Processing FooController#create to json (for 127.0.0.1 at 2009-08-07 11:52:33) [POST] Parameters: {"foo"=>"1","api_key"=>"44a895ca30e95a3206f961fcd56011d364dff78e","bar"=>"202"} ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken): thin (1.2.2) lib/thin/connection.rb:76:in `pre_process' thin (1.2.2) lib/thin/connection.rb:74:in `catch' thin (1.2.2) lib/thin/connection.rb:74:in `pre_process' thin (1.2.2) lib/thin/connection.rb:57:in `process' thin (1.2.2) lib/thin/connection.rb:42:in `receive_data' eventmachine (0.12.8) lib/eventmachine.rb:242:in `run_machine' eventmachine (0.12.8) lib/eventmachine.rb:242:in `run' thin (1.2.2) lib/thin/backends/base.rb:57:in `start' thin (1.2.2) lib/thin/server.rb:156:in `start' thin (1.2.2) lib/thin/controllers/controller.rb:80:in `start' thin (1.2.2) lib/thin/runner.rb:174:in `send' thin (1.2.2) lib/thin/runner.rb:174:in `run_command' thin (1.2.2) lib/thin/runner.rb:140:in `run!' thin (1.2.2) bin/thin:6 /opt/local/bin/thin:19:in `load' /opt/local/bin/thin:19
解决方法
启用protect_from_forgery后,Rails需要任何非GET请求的真实性令牌. Rails将自动包含使用AJAX助手创建的表单助手或链接创建的表单中的真实性令牌,因此在正常情况下,您不必考虑它.
如果您不使用内置的Rails表单或AJAX帮助者(也许您正在使用不引人注目的JS或使用JS MVC框架),则必须将客户端的令牌设置在客户端,并将其与您的提交POST请求时的数据.你会把这样一条线放在< head>的布局:
<%= javascript_tag "window._token = '#{form_authenticity_token}'" %>
那么你的AJAX函数会用你的其他数据(例如jQuery)来发布令牌:
$.post(url,{ id: theId,authenticity_token: window._token });