Rails 4 Authenticity Token
我在开发新的Rails4应用程序(Ruby2.0.0-p0)时遇到了一些真实性令牌问题。
在编写响应JSON的控制器(使用
我确定我设置了
我尝试使用Rails3.2(Ruby1.9.3)编写相同的控制器,但没有发现任何真实性令牌问题。我四处搜索,发现Rails4中的真实性令牌发生了一些变化。据我所知,它们不再自动插入表单中了?我想这在某种程度上影响了非HTML内容类型。
有没有什么方法可以在不需要请求HTML表单、获取真实性令牌、然后使用该令牌进行另一个请求的情况下解决这个问题?还是我完全错过了一些显而易见的东西?
编辑:我刚尝试在一个新的Rails4应用程序中创建一个新的记录,但没有改变任何东西,我遇到了同样的问题,所以我想这不是我做的事情。
我想我刚刚明白了。我更改了(新)默认值
1 | protect_from_forgery with: :exception |
到
1 | protect_from_forgery with: :null_session |
号
根据
1 2 | # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. |
您可以通过查看
在轨道3.2中:
1 2 3 4 5 6 | # This is the method that defines the application behavior when a request is found to be unverified. # By default, ails resets the session when it finds an unverified request. def handle_unverified_request reset_session end |
。
在轨道4中:
1 2 3 | def handle_unverified_request forgery_protection_strategy.new(self).handle_unverified_request end |
这将调用以下内容:
1 2 3 | def handle_unverified_request raise ActionController::InvalidAuthenticityToken end |
。
与其关闭CSRF保护,不如在表单中添加以下代码行
1 | <%= tag(:input, :type =>"hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %> |
如果您使用form_for或form_标记生成表单,那么它将自动在表单中添加上述代码行。
将以下行添加到对我有效的表单中:
1 | <%= hidden_field_tag :authenticity_token, form_authenticity_token %> |
。
我认为一般来说,只要不专门实现API,就关闭CSRF保护是不好的。
在查看ActionController的Rails4API文档时,我发现您可以关闭每个控制器或每个方法库上的伪造保护。
例如,为您可以使用的方法关闭CSRF保护
1 2 | class FooController < ApplicationController protect_from_forgery except: :index |
。
遇到了同样的问题。通过添加到我的控制器来修复它:
1 | skip_before_filter :verify_authenticity_token, if: :json_request? |
。
你试过了吗?
1 | protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format.json? } |
号
这个官方文件讨论了如何正确关闭API的伪造保护http://api.rubyonrails.org/classes/actionController/requestForgeryProtection.html
这是Rails中的一个安全功能。在表单中添加此行代码:
1 | <%= hidden_field_tag :authenticity_token, form_authenticity_token %> |
。
文档可在此处找到:http://api.rubyonrails.org/classes/actionController/requestForgeryProtection.html
这些功能是为了安全和伪造保护而添加的。
但是,为了回答您的问题,这里有一些输入。您可以在控制器名称后添加这些行。
就像这样,
1 2 | class NameController < ApplicationController skip_before_action :verify_authenticity_token |
号
以下是不同版本的Rails的一些线条。
轨道3
skip_before_filter :verify_authenticity_token
号
轨道4:
skip_before_action :verify_authenticity_token
号
< BR>如果您打算对所有控制器例程禁用此安全功能,则可以将应用程序的protect_from_forgery的值更改为:null_session_controller.rb文件。
就像这样,
1 2 3 | class ApplicationController < ActionController::Base protect_from_forgery with: :null_session end |
号
将EDOCX1[2]添加到表单标记中
如果将jquery与rails一起使用,请注意不要允许在不验证真实性令牌的情况下输入方法。
jquery ujs可以为您管理令牌
您应该已经将它作为jquery rails gem的一部分,但是您可能需要将它包含在application.js中,
1 | //= require jquery_ujs |
号
这就是您所需要的-您的Ajax调用现在应该可以工作了
有关详细信息,请参阅:https://github.com/rails/jquery-ujs网站
我所有的测试都正常。但出于某种原因,我将环境变量设置为非测试:
1 | export RAILS_ENV=something_non_test |
号
我忘记了取消设置这个变量,因为我开始获取
在取消设置
定义自己的HTML表单时,必须包含身份验证令牌字符串,出于安全原因,该字符串应发送到控制器。如果您使用Rails表单帮助器来生成真实性令牌,那么将按如下方式添加到表单中。
1 2 3 4 5 6 7 | <form accept-charset="UTF-8" action="/login/signin" method="post"> <input name="utf8" type="hidden" value="✓" /> <input name="authenticity_token" type="hidden" value="x37DrAAwyIIb7s+w2+AdoCR8cAJIpQhIetKRrPgG5VA="> ... </form> |
因此,解决这个问题的方法要么是添加真实性令牌字段,要么使用Rails表单帮助器,而不是牺牲安全性等。