当我遇到一些真实性令牌问题时,我正在开发一个新的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>
答案 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="✓" />
<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
后,我的测试再次开始工作。