我正在尝试实现基于令牌的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
答案 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_session
与 protect_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
的原因。
资源:
仅此而已。
我希望这会有所帮助