首页 文章

Rails 4真实性令牌

提问于
浏览
196

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

在编写响应json的控制器时(使用 respond_to 类方法),当我尝试使用 curl 创建记录时,我得到了 create 动作,我开始得到 ActionController::InvalidAuthenticityToken 异常 .

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

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

有没有办法解决这个问题,而无需请求HTML表单,抢夺真实性令牌,然后使用该令牌发出另一个请求?还是我完全错过了一些非常明显的东西?

Edit: 我刚尝试使用脚手架在一个新的Rails 4应用程序中创建一个新记录,而没有改变任何东西,我没有做过我做过的事情 .

13 回答

  • 8

    将以下行添加到表单中对我有用:

    <%= hidden_field_tag :authenticity_token, form_authenticity_token %>
    
  • 0

    我想我只想出来了 . 我更改了(新)默认值

    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
    

    这将调用the following

    def handle_unverified_request
      raise ActionController::InvalidAuthenticityToken
    end
    
  • 1

    不要关闭csrf保护,最好将以下代码行添加到表单中

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

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

  • 1

    只要您不专门实施API,我认为通常不关闭CSRF保护是件好事 .

    在查看ActionController的Rails 4 API文档时,我发现您可以在每个控制器或每个方法基础上关闭伪造保护 .

    例如,为您可以使用的方法关闭CSRF保护

    class FooController < ApplicationController
      protect_from_forgery except: :index
    
  • 69

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

    skip_before_filter :verify_authenticity_token, if: :json_request?
    
  • 4

    你试过了吗?

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

    这个官方文档 - 讨论如何正确关闭api的伪造保护http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html

  • 2

    这是Rails中的安全功能 . 在表单中添加以下代码行:

    <%= hidden_field_tag :authenticity_token, form_authenticity_token %>
    

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

  • 70

    添加这些功能是为了安全和防伪目的 .
    但是,要回答你的问题,这里有一些输入 . 您可以在控制器名称后添加这些行 .

    像这样,

    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

    如果要为所有控制器例程禁用此安全功能,可以在application_controller.rb文件上将 protect_from_forgery 的值更改为 :null_session .

    像这样,

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

    如果您正在使用带有rails的jQuery,请注意允许在不验证真实性令牌的情况下进入方法 .

    jquery-ujs可以为您管理令牌

    您应该将它作为jquery-rails gem的一部分,但您可能需要将它包含在application.js中

    //= require jquery_ujs
    

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

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

  • 0

    authenticity_token: true 添加到表单标记

  • 3

    当您定义自己的html表单时,您必须包含身份验证令牌字符串,出于安全原因应该将其发送到控制器 . 如果使用rails form helper生成真实性令牌,则添加形式如下 .

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

    因此问题的解决方案是添加authenticity_token字段或使用rails形式帮助程序而不是危及安全性等 .

  • 32

    我的所有测试都运行良好 . 但由于某种原因,我将环境变量设置为非测试:

    export RAILS_ENV=something_non_test
    

    我忘了取消设置这个变量,因为我开始得到 ActionController::InvalidAuthenticityToken 异常 .

    取消设置 $RAILS_ENV 后,我的测试再次开始工作 .

相关问题