1

我在一个项目中玩设计,只是想更好地理解它是如何工作的。特别是 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

我认为这些方法正在增加某种安全性。我只是想知道他们到底在保护什么。

4

1 回答 1

2

的实现devise_parameter_sanitizer是创建一个ParameterSanitizer实例。我经常发现查看测试有助于理解代码的目的。我认为这个测试最能说明这一点 - 因为您正在创建一个新用户,所以您不希望允许用户将他们想要的任何值分配给他们想要的任何参数,因此sanitize意味着“去除除这些属性之外的任何属性我们需要采取这一行动”。如果这不在这里,并且您有一个role属性,那么用户可以在注册您的站点时发送一个特制的 POST 请求,使自己成为管理员。因此,这可以防止通常情况下所谓的批量分配漏洞Rails 3 和 Rails 4 以不同的方式防止这种情况发生但是保护仍然可以关闭,我猜 Devise 正在尝试设置一些好的实践默认值。

serialize_options方法是创建一个选项散列以支持呈现为 XML 或 JSON。我通过查看的实现responds_with发现了这一点,extract_options!如果最后一个参数是Hash. 文档responds_with说“给#respond_with的所有选项都发送给底层响应者”,所以我查看了ActionController::Responder,其文档解释了查找与格式匹配的模板所需的过程,如果找不到,则调用to_#{format},然后调用to_format。有一个 HTML 视图,ActiveRecord对象响应to_xmlto_json。这些方法使用这些选项

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 格式,这可以防止您暴露比您可能想要的更多信息。

于 2013-10-24T01:50:48.187 回答