1

私のRoRアプリケーションではdeviseを使用しており、クライアントは少しカスタマイズする必要があります. これを処理するカスタム アクション、つまりユーザー コントローラーで独自の 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

ここに routes.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に設定したことです。他のユーザーの詳細を編集できますが、パスワードを編集できません。何が起きてる?

4

1 に答える 1

2

この問題を解決する方法はたくさんあります。いくつか説明してみます。

あなたの問題の鍵は、あなたがMassAssignmentSecurity役割を混同していることだと思います. 役割に対してと役割Whitelistに対してを定義しました。このエラーは、ロールにあるものを割り当てようとしたことを示しています。adminBlacklistdefaultBlacklistdefault

さまざまな役割を定義しているので、おそらく次のように修正したいと思います。

管理者を変更する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#mass-assignment

それが役立つことを願っています。

于 2013-01-15T16:16:47.940 に答える