在特定密码更改页面更改其他用户密码时,设计 - 批量分配错误 [英] Devise - mass assignment error when changing other users passwords in specific password change page

查看:111
本文介绍了在特定密码更改页面更改其他用户密码时,设计 - 批量分配错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的RoR应用程序中,我正在使用devise,客户端需要一些定制 - 基本上他要求管理员能够更改其他用户的密码,密码更改页面不同于编辑个人资料详细信息的页面。我已经设置了自定义操作来处理这个,即我自己的用户控制器中的change_password操作。

 用户控制器操作
def change_password
@user = User.find(params [:id])
end

def update_password#我发布到这个
@user = User.find params [:id])
if @ user.update_attributes!(params [:user])
redirect_to users_path,:notice => 用户更新。
else
redirect_to users_path,:alert => 无法更新用户。
end
end

回收routes.rb条目

  devise_for:users,:skip => [:registration] 
as:user do
get'users / edit'=> 'devise / registrations#edit',:as => 'edit_user_registration'
put'users'=> 'devise / registrations#update',:as => 'user_registration'
end
资源:用户
...

匹配/ 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
#包含默认设计模块。其他可用的是:
#:token_authenticatable,:confirmable,
#:lockable,:timeoutable and:omniauthable,:registerable,
devise:database_authenticatable,#:可注册,
:可恢复:可记住,可追踪,可验证

#模型的可访问(或保护)属性
attr_accessible:role_ids,as 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

但是我不断得到这个质量属性分配错误

 无法大量分配受保护的属性:password,password_confirmation 

奇怪的是我已将所有这些属性设置为accessible_protected。我可以编辑其他用户的详细信息,但无法编辑他们的密码。

解决方案

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



我认为你的问题的关键是你正在混合 MassAssignmentSecurity 角色。您为 admin 角色定义了一个白名单黑名单默认角色。错误表示您尝试为默认角色的黑名单分配一些内容。



由于您正在定义不同的角色,我认为您可能希望以这种方式进行修复:



更改您的管理员白名单

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

然后分配为admin:

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

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



另一个选项是坚持默认角色。您可以通过两种方式绕过安全性。



我不推荐的第一个选项是不将密码和密码确认作为用户 params,并在您的视图中单独发送。然后,您可以手动设置这些字段:

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

但是,执行以下操作更容易,只需跳过保护:

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

有关更多信息,本指南相当不错:
http://guides.rubyonrails.org/security.html#mass-assignment



我希望有帮助。


In my RoR application I'm using devise and the client requires a bit of customisation - basically he requires that the administrator be able to change passwords of other users and that the password change page be different than the page to edit profile details. I've set up custom actions to handle this namely my own change_password action in users controller.

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

Heres the routes.rb entries

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

And this is my users model

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

however I keep getting this mass attributes assignment error

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

the weird thing is that I've set all these attributes to accessible_protected. I can edit other users details but can't edit their passwords. Whats going on here?

解决方案

There are many ways you can fix this problem. I'll try to explain a few.

I think the key to your problem is that you are mixing up the MassAssignmentSecurity roles. You've defined a Whitelist for the admin role and a Blacklist for the default role. The error says that you tried to assign something that was on the Blacklist for the default role.

Since you are defining different roles, I assume you probably want to fix it this way:

Change your admin Whitelist

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

Then assign as the admin:

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

(If your controller action includes fields other than the password fields, this may cause new violations.)

A different option is to stick to the default role. You can bypass security a couple ways.

The first option which I don't recommend is to not pass the password and password confirmation as part of the User params, and send them separately in your view. You can then manually set those fields like so:

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

However, it's even easier to do the following to just skip protection:

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

For more information, this guide is fairly good: http://guides.rubyonrails.org/security.html#mass-assignment

I hope that helps.

这篇关于在特定密码更改页面更改其他用户密码时,设计 - 批量分配错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆