Rails 4真实性令牌
当我遇到一些真实性令牌问题时,我正在研究一个新的Rails 4应用程序(在Ruby 2.0.0-p0上)。
在编写一个响应json的控制器时(使用respond_to
类方法),当我尝试使用curl
创buildlogging时,我得到了create
操作,我开始获取ActionController::InvalidAuthenticityToken
exception。
我确定我设置了-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="✓" /> <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