在Oreg_from_forgery中,exception和null_session的含义是什么

时间:2016-04-20 02:45:47

标签: ruby-on-rails

我正在尝试实现基于令牌的API,并通过谷歌

看到了这个片段

然而,字面意思很难理解其含义。

关于此的任何方向或基本知识,谢谢~~

class ApplicationController < ActionController::Base

  protect_from_forgery with: :exception, if: Proc.new { |c| c.request.format != 'application/json' }
  protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
end

2 个答案:

答案 0 :(得分:5)

关于null_session的Rails文档在http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession.html#method-i-handle_unverified_request,如果你查看它的handle_unverified_request方法的源代码:

def handle_unverified_request
  request = @controller.request
  request.session = NullSessionHash.new(request.env)
  request.env['action_dispatch.request.flash_hash'] = nil
  request.env['rack.session.options'] = { skip: true }
  request.env['action_dispatch.cookies'] = NullCookieJar.build(request)
end

这意味着如果请求没有通过verify_authenticity_token,则rails将不会通过cookie数据获取会话,而是为此请求创建一个新会话。那个会话是NullSessionHash的一个实例,所以&#34; null_session&#34;。

答案 1 :(得分:0)

我在开发一个仅使用 Rails 6 API 的应用程序时遇到了这个问题。

默认情况下,Rails 将跨站请求伪造 (CSRF) 保护应用于所有从 ApplicationController 使用以下行的子类的控制器:

protect_from_forgery with: :exception

但是在某些情况下,您是否希望做出不同的响应,甚至完全忽略 CSRF 保护?答案当然是肯定的。

如果您的项目或项目的一部分使用替代方法进行身份验证,例如 API 令牌或任何其他“无状态”身份验证,那么您可以安全地从这些控制器继承的任何基类中删除 protect_from_forgery 行。

另一方面,如果您的项目使用有状态身份验证和 API,例如那些具有大量 AJAX 请求的项目,那么将 :null_sessionprotect_from_forgery 一起使用可能是有利的:

protect_from_forgery with: :null_session

这意味着用户将不再登录该操作并且无法执行更改(如果该操作需要登录用户)。但是,在操作之后,会话值将返回并且会话 ID 将相同,因此用户将登录。

它不会抛出您的 JavaScript 可能无法处理的异常,而是在操作期间将会话值设置为 nil。通过这样做,任何作用于当前用户的授权或操作都会导致错误,您的 JavaScript 可以更轻松地处理这些错误。

因此,如果您正在开发仅Rails API 的应用程序,您可以使用它来防止跨站请求伪造 (CSRF) 攻击。当它们中的任何一个出现时,这对于两种情况就足够了:

class ApplicationController < ActionController::API
  include ActionController::RequestForgeryProtection

  if Proc.new { |c| c.request.format != 'application/json' }
    protect_from_forgery with: :exception
  end
    
  if Proc.new { |c| c.request.format == 'application/json' }
    protect_from_forgery with: :null_session
  end
end

这在您的请求不是 protect_from_forgery with: :exception 格式时实现 application/json,当您的请求是 protect_from_forgery with: :null_session 格式时实现 application/json

注意protect_from_forgery 是包含在 ActionController::RequestForgeryProtection 中的类方法,这就是包含 include ActionController::RequestForgeryProtection 的原因。

资源

  1. CSRF Protection and Ruby on Rails
  2. Undefined method protect_from_forgery for Clearance::SessionsController:Class

仅此而已。

我希望这会有所帮助