Rails 4真实性令牌

时间:2013-04-28 02:25:34

标签: ruby-on-rails ruby ruby-on-rails-4 authenticity-token

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

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

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

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

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

编辑:我刚尝试使用脚手架在新的Rails 4应用中创建新记录而不更改任何内容我遇到了同样的问题所以我想这不是我做的事情。< / p>

13 个答案:

答案 0 :(得分:273)

我想我只是想通了。我更改了(新)默认

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 :(得分:71)

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

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

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

答案 2 :(得分:70)

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

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

答案 3 :(得分:32)

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

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

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

class FooController < ApplicationController
  protect_from_forgery except: :index

答案 4 :(得分:8)

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

      skip_before_filter :verify_authenticity_token, if: :json_request?

答案 5 :(得分:7)

你尝试过吗?

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

答案 6 :(得分:4)

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

答案 7 :(得分:3)

这是Rails中的安全功能。在以下格式中添加以下代码:

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

可在此处找到文档: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html

答案 8 :(得分:2)

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

像这样,

class NameController < ApplicationController
    skip_before_action :verify_authenticity_token

以下是不同版本的rails的一些行。

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

答案 9 :(得分:1)

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

jquery-ujs可以为你管理令牌

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

//= require jquery_ujs

这就是你所需要的 - 你的ajax调用现在可以正常工作

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

答案 10 :(得分:1)

authenticity_token: true添加到表单标记

答案 11 :(得分:0)

当您定义自己的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形式帮助程序而不是危及安全性等。

答案 12 :(得分:0)

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

export RAILS_ENV=something_non_test

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

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