在特定密码更改页面更改其他用户密码时,设计 - 批量分配错误 [英] Devise - mass assignment error when changing other users passwords in specific password change page
问题描述
用户控制器操作
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屋!