在特定的密码更改页面更改其他用户的密码时,会出现大量分配错误



在我的RoR应用程序中,我使用的是设计,客户端需要一些定制—基本上他要求管理员能够更改其他用户的密码,并且密码更改页面与编辑配置文件详细信息的页面不同。我已经设置了自定义动作来处理这个,即我自己的change_password动作在用户控制器。

Users Controller Actions
def change_password
    @user = User.find(params[:id])
  end
  def update_password # I post to this
    @user = User.find(params[:id])
    if @user.update_attributes!(params[:user])
      redirect_to users_path, :notice => "User updated."
    else
      redirect_to users_path, :alert => "Unable to update user."
    end
  end

下面是路由。rb条目

devise_for :users, :skip => [:registrations]                                          
    as :user do
      get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'    
      put 'users' => 'devise/registrations#update', :as => 'user_registration'            
    end
  resources :users
...
  match "/users/:id/change_password" =>"users#change_password", :as=>:change_password_user, :via=>:get
  match "/users/:id/update_password" => "users#update_password", :as=>:update_password_user, :via=>:post

这是用户模型

class User < ActiveRecord::Base
  rolify
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable, :registerable,
  devise :database_authenticatable, #:registerable,
         :recoverable, :rememberable, :trackable, :validatable
  # Setup accessible (or protected) attributes for your model
  attr_accessible :role_ids, :as => :admin
  attr_protected :username, :name, :email, :password, :password_confirmation, :remember_me
  validates_uniqueness_of :username
  validates_presence_of :username, :email
  validates_uniqueness_of :email
end

但是我一直得到这个质量属性分配错误

Can't mass-assign protected attributes: password, password_confirmation

奇怪的是,我把所有这些属性都设置为accessible_protected。我可以编辑其他用户的详细信息,但不能编辑他们的密码。这是怎么回事?

有很多方法可以解决这个问题。我会试着解释一些。

我认为你的问题的关键是你混淆了MassAssignmentSecurity的角色。您已经为admin角色定义了Whitelist,为default角色定义了Blacklist。错误提示您试图为default角色分配Blacklist上的内容。

既然你定义了不同的角色,我假设你可能想要这样修复它:

更改admin Whitelist

attr_accessible :role_ids, :password, :password_confirmation, as: :admin

然后指定为管理员:

if @user.update_attributes!(params[:user], as: :admin)

(如果您的控制器操作包含密码字段以外的字段,这可能会导致新的违规。)

另一种选择是坚持默认角色。你可以通过几种方式绕过安全保护。

我不推荐的第一个选项是不将密码和密码确认作为User参数的一部分传递,并在您的视图中单独发送它们。然后,您可以像这样手动设置这些字段:

@user.assign_attributes(params[:user])
@user.password = params[:password]
@user.password_confirmation = params[:password_confirmation]
if @user.save!

但是,跳过保护更简单:

@user.assign_attributes(params[:user], without_protection: true)
if @user.save!

更多信息,这个指南是相当不错的:http://guides.rubyonrails.org/security.html质量确定

相关内容

  • 没有找到相关文章

最新更新