在注册/编辑中设计不保存密码更改

时间:2015-05-22 21:15:47

标签: ruby-on-rails devise

我的Devise注册控制器中有一些自定义字段,并在Application_controller中进行设置:

def configure_permitted_parameters
  devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_password, :remember_me) }
end

这是我的编辑注册表:

<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
  <%= f.error_notification %>
<div class="form-inputs">
    <%= f.input :email, required: true, autofocus: true, placeholder: "Email" %>
<br>
<%= f.input :password, autocomplete: "off", hint: "Leave blank if you are not changing your password", required: false, placeholder: "Password" %>
<br>
<%= f.input :password_confirmation, required: false, placeholder: "Password Confirmation" %>



  <div class="form-actions">
     <%= link_to "Back to Home Page", user_landings_path, :class => 'btn btn-success' %>
    <%= f.submit 'Update', :class => 'btn btn-primary' %>
  </div>
<% end %>

已保存电子邮件更改,但未保存密码。

任何提示?

修改

如果重要的话,我也绕过了用户输入当前密码来更新帐户的要求:

class RegistrationsController&lt;设计:: RegistrationsController

protected

  def update_resource(resource, params)
    resource.update_without_password(params)
  end

2 个答案:

答案 0 :(得分:2)

我过去通过手动为资源分配密码解决了这个问题。在update_resource(或您可能需要的任何地方)覆盖设计方法RegistrationsController。这将确保密码在params中传递时更新,然后处理任何其他属性。

  def update_resource(resource, params)
    if params[:password]
      resource.password = params[:password]
      resource.password_confirmation = params[:password_confirmation]
    end

    resource.update_without_password(params)
  end

它有点像猴子补丁,但完成了工作。

答案 1 :(得分:0)

这种行为正是Divises作者所希望的。他们不希望用户在不显示当前密码的情况下更改密码,因为它可能存在安全问题。假设您在去咖啡时让机器解锁,而您的室友在您登录的网站上更改了密码。不酷,对吧?因此,我自己决定最好的办法是分离编辑配置文件和更改密码操作,这样您就可以在不显示current_password的情况下更改配置文件,但是为了更改密码,您应该提供它。

密码未更新的确切原因是设计update_without_password 方法实现(注意params.delete和authors&#39; comment):

# Updates record attributes without asking for the current password.
# Never allows a change to the current password. If you are using this
# method, you should probably override this method to protect other
# attributes you would not like to be updated without a password.

def update_without_password(params, *options)
  params.delete(:password)
  params.delete(:password_confirmation)

  result = update_attributes(params, *options)
  clean_up_passwords
  result
end

现在注意他们如何在update_with_password方法中使密码可选(注意id params [:密码] .blank?block):

def update_with_password(params, *options)
  current_password = params.delete(:current_password)

  if params[:password].blank?
    params.delete(:password)
    params.delete(:password_confirmation) if params[:password_confirmation].blank?
  end

  result = if valid_password?(current_password)
    update_attributes(params, *options)
  else
    self.assign_attributes(params, *options)
    self.valid?
    self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
    false
  end

  clean_up_passwords
  result
end

您的问题的确切解决方案是覆盖update_without_params方法,以有条件地从params中删除密码,就像在update_with_password方法中一样。但我个人并不建议这样做,因为可能存在安全问题。在我看来,更好的解决方案是分离配置文件编辑和密码更改的视图。