Rails 4真实性令牌

当我遇到一些真实性令牌问题时,我正在研究一个新的Rails 4应用程序(在Ruby 2.0.0-p0上)。

在编写一个响应json的控制器时(使用respond_to类方法),当我尝试使用curl创buildlogging时,我得到了create操作,我开始获取ActionController::InvalidAuthenticityTokenexception。

我确定我设置了-H "Content-Type: application/json" ,我用-d "<my data here>"设置了数据,但仍然没有运气。

我尝试使用Rails 3.2编写相同的控制器(在Ruby 1.9.3上),并且我没有任何真实性令牌问题。 我search了四周,我发现Rails 4中的真实性令牌发生了一些变化。据我所知,它们不再自动插入到表单中了吗? 我想这是以某种方式影响非HTML内容types。

有没有什么办法可以解决这个问题,而不需要请求一个HTML表单,抢走真实性标记,然后用这个标记做出另一个请求? 还是我完全错过了一些完全明显的东西?

编辑:我只是尝试在一个新的Rails 4应用程序创build一个新的logging使用脚手架而不改变任何东西,我遇到了同样的问题,所以我想这不是我做的。

    我想我只是想出来了。 我改变了(新的)默认值

     protect_from_forgery with: :exception 

     protect_from_forgery with: :null_session 

    根据ApplicationController的注释。

     # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. 

    您可以通过查看request_forgery_protecton.rb的源代码,或者更具体地来看以下几行来看到不同之处:

    在Rails 3.2中 :

     # This is the method that defines the application behavior when a request is found to be unverified. # By default, \Rails resets the session when it finds an unverified request. def handle_unverified_request reset_session end 

    在Rails 4 :

     def handle_unverified_request forgery_protection_strategy.new(self).handle_unverified_request end 

    这将会调用以下内容 :

     def handle_unverified_request raise ActionController::InvalidAuthenticityToken end 

    而不是closurescsrf保护,最好将下面的代码行添加到表单中

     <%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %> 

    如果您使用form_for或form_tag生成表单,则会自动在表单中添加上面的代码行

    将以下行添加到表单中为我工作:

     <%= hidden_field_tag :authenticity_token, form_authenticity_token %> 

    只要你不专门实现一个API,我认为通常closuresCSRF保护是不好的。

    在查看ActionController的Rails 4 API文档时,我发现您可以closures每个控制器或每个方法的伪造保护。

    例如,closures您可以使用的方法的CSRF保护

     class FooController < ApplicationController protect_from_forgery except: :index 

    遇到同样的问题。 通过添加到我的控制器来修复它:

      skip_before_filter :verify_authenticity_token, if: :json_request? 

    你试过了吗?

      protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format.json? } 

    这个官方文件 – 谈到如何正确closures对api的伪造保护http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html

    这是Rails中的一个安全特性。 以下面的forms添加这行代码:

     <%= hidden_field_tag :authenticity_token, form_authenticity_token %> 

    文档可以在这里find: http : //api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html

    这些function是为了安全和伪造保护目的而添加的。
    但是,要回答你的问题,这里有一些input。 您可以在控制器名称后添加这些行。

    像这样,

     class NameController < ApplicationController skip_before_action :verify_authenticity_token 

    这里有一些不同版本的导轨。

    Rails 3

    skip_before_filter:verify_authenticity_token

    Rails 4

    skip_before_action:verify_authenticity_token

    如果您打算为所有控制器例程禁用此安全function,则可以在application_controller.rb文件中将protect_from_forgery的值更改:null_session

    像这样,

     class ApplicationController < ActionController::Base protect_from_forgery with: :null_session end 

    authenticity_token: true添加到表单标记

    当你定义你自己的html表单时,你必须包含身份validation令牌string,为了安全起见,这个string应该发送给控制器。 如果你使用railsforms的助手来生成真实性令牌,那么添加forms如下。

     <form accept-charset="UTF-8" action="/login/signin" method="post"> <div style="display:none"> <input name="utf8" type="hidden" value="&#x2713;" /> <input name="authenticity_token" type="hidden" value="x37DrAAwyIIb7s+w2+AdoCR8cAJIpQhIetKRrPgG5VA="> </div> ... </form> 

    所以问题的解决scheme是要么添加authenticity_token字段,要么使用railsforms助手,而是妥协安全等。

    如果您使用带有rails的jQuery,请不要在validation真实性标记的情况下允许进入方法。

    jquery-ujs可以为你pipe理令牌

    你应该已经把它作为jquery-rails gem的一部分,但是你可能需要把它包含在application.js中

     //= require jquery_ujs 

    这就是你所需要的 – 你的ajax调用现在应该可以工作

    有关更多信息,请参阅: https : //github.com/rails/jquery-ujs