我在一个项目中玩Devise,我只是想更好地理解它是如何工作的。特别是Sessions控制器正在做一些我不理解的事情:
class Devise::SessionsController < ApplicationController
def new
# What benefit is this providing over just "resource_class.new"?
self.resource = resource_class.new(sign_in_params)
clean_up_passwords(resource)
# What is "serialize_options" doing in the responder?
respond_with(resource, serialize_options(resource))
end
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_sign_in_path_for(resource)
end
...
protected
...
def serialize_options(resource)
methods = resource_class.authentication_keys.dup
methods = methods.keys if methods.is_a?(Hash)
methods << :password if resource.respond_to?(:password)
{ :methods => methods, :only => [:password] }
end
def sign_in_params
devise_parameter_sanitizer.sanitize(:sign_in)
end
end
我认为这些方法正在增加某种安全性。我只是想知道他们到底要保护什么。
答案 0 :(得分:2)
The implementation of devise_parameter_sanitizer
正在创建ParameterSanitizer个实例。我经常发现测试有助于理解代码的目的;和this test我认为最好说明一点 - 因为您正在创建新用户,您不希望允许用户将他们想要的任何值分配给他们想要的任何参数,因此sanitize
表示“除去我们为此行动所需的任何属性“。如果不在此处,并且您具有role
属性,则用户可以在注册您的网站时发送特制的POST请求,以使自己成为管理员。因此,在一般情况下,这可以防止所谓的mass assignment vulnerability。 Rails 3 and Rails 4 protect against this in different ways但保护措施仍然可以关闭,我猜测Devise正试图设置一些良好的练习默认值。
serialize_options
方法正在创建一个选项哈希,以支持呈现XML或JSON。我通过查看the implementation of responds_with
找到了这一点,ActionController::Responder
调用extract_options!
,如果最后一个参数是Hash
,则使用最后一个参数作为选项。 responds_with
的文档说“给#respond_with的所有选项都发送给底层响应者”,所以我查看了use those options,其文档说明了查找与格式匹配的模板所需的过程,如果找不到,请拨打to_#{format}
,然后拨打to_format
。有一个HTML视图,ActiveRecord
个对象响应to_xml
和to_json
。那些方法{{3}}:
The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the
attributes included, and work similar to the +attributes+ method.
To include the result of some method calls on the model use <tt>:methods</tt>.
因此,如果有人使用XML或JSON格式,这可以防止您暴露出比您想要的更多的信息。