Rails 4:无法验证CSRF令牌的真实性,但数据仍插入数据库



我通过添加以下内容在控制器中应用CSRF

  class ApplicationController < ActionController::Base
     protect_from_forgery
  end

并且我使用Postman向我的API发出发布请求。有趣的结果是,我无法验证CSRF,但我发送的数据仍然插入到DB中。

这是服务器日志。

 Processing by Api::ListingsController
   Parameters: {"listing"=>{...}}
 Can't verify CSRF token authenticity
   (0.2ms)  BEGIN
 SQL (0.6ms)  INSERT INTO "listings" ...
   (0.4ms)  COMMIT
 Completed 201 Created in 54ms (Views: 0.2ms | ActiveRecord: 6.3ms)

看起来一切都很好,数据现在在数据库中!为什么CSRF不起作用?

有人能解释一下吗?

csrf令牌不匹配可能触发3种行为:

  • 引发异常(:exception
  • 将会话重置为新的空会话(:reset_session
  • 对请求使用空会话,但不要完全重置(:null_session

最后2个的理由是,CSRF攻击的目的通常是滥用用户已经登录的事实,因此浏览器将在请求中发送会话cookie。因此,重新设置或忽略会话(假设存储凭据的位置)将使请求作为未经身份验证的请求继续进行。

如果应用程序不要求用户登录,则:null_session:reset_session将允许请求继续进行。

多年来,默认行为发生了变化,但自轨道4.2起为:null_session。您可以通过将with选项指定为protect_from_forgery 来更改它

ApplicationController中,您可以添加

class ApplicationController < ActionController::Base
    protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format      == 'application/json' }
    # Or
    # skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }
end

最新更新