Rails 4真实性令牌

ale*_*oco 198 ruby ruby-on-rails authenticity-token ruby-on-rails-4

当我遇到一些真实性令牌问题时,我正在研究一个新的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应用程序中创建一个新记录而不改变任何东西,我遇到了同样的问题所以我想这不是我做的事情.

ale*_*oco 275

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

protect_from_forgery with: :exception
Run Code Online (Sandbox Code Playgroud)

protect_from_forgery with: :null_session
Run Code Online (Sandbox Code Playgroud)

根据评论ApplicationController.

# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
Run Code Online (Sandbox Code Playgroud)

您可以通过查看源代码来查看差异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
Run Code Online (Sandbox Code Playgroud)

Rails 4中:

def handle_unverified_request
  forgery_protection_strategy.new(self).handle_unverified_request
end
Run Code Online (Sandbox Code Playgroud)

这将调用以下内容:

def handle_unverified_request
  raise ActionController::InvalidAuthenticityToken
end
Run Code Online (Sandbox Code Playgroud)

  • 您可以一起删除:with选项,:null_session是默认值:http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html (20认同)
  • 有没有办法为非JSON调用使用异常,为JSON调用(又称API调用)使用null会话? (6认同)

xia*_*boa 71

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

<%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %> 
Run Code Online (Sandbox Code Playgroud)

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

  • 如果您正在制作表单,这是一个很好的建议,但问题是指使用JSON进行API调用. (9认同)

小智 70

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

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
Run Code Online (Sandbox Code Playgroud)

  • 并不真正适用于api电话 (12认同)
  • 比上面的代码更简洁.谢谢! (2认同)
  • 就我而言,我正在使用Rails4.我可以点击提交按钮提交表单.但是,如果我通过JS代码提交表单,则会发生此错误.这个答案为我解决了问题. (2认同)
  • 对于我的基于Rails 4.0.8的应用程序,只需编写`= token_tag nil`或(在.erb中)`<%= token_tag nil%>` (2认同)

小智 33

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

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

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

class FooController < ApplicationController
  protect_from_forgery except: :index
Run Code Online (Sandbox Code Playgroud)


小智 9

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

      skip_before_filter :verify_authenticity_token, if: :json_request?
Run Code Online (Sandbox Code Playgroud)


zec*_*htz 7

你试过了吗?

 protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format.json? }
Run Code Online (Sandbox Code Playgroud)


kon*_*ung 5

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