まずStrongParameterとは
StrongParametersとはMass Assignment機能を利用する際、起こり得る脆弱性へ対抗する手段の一つである。
ではMass Assignmentとは
Mass Assignmentとはモデルの生成や更新の際に、Rubyのハッシュを使って一括で属性を設定できるとても便利な仕組みである。
以下はMass Assignmentを使用せずに個別に値を設定
irb(main):001:0> book = Book.last
irb(main):002:0> book.name = "キングダム"
irb(main):003:0> book.price = 1980
irb(main):004:0> book.save
以下はMass Assignment機能を使用し、データを更新
irb(main):001:0> num = {name: "キングダム", price: 2980}
irb(main):002:0> book = Book.last
irb(main):003:0> book.update(num)
上記の仕組みを使用することで複数の属性設定を簡単に記述することが可能になるが、不用意に使うとアプリケーションに脆弱性を出してしまう
具体的には意図しない変更をユーザーに許してしまう(管理者権限を付与してしまうなど)
これを防ぐためにある機能がStrongParametersである
StrongParametesはMass Assignmentで利用しても良いHashのkeyを許可リストとして定義しておくことで想定しないパラメーターを利用しないように制限する。
def update
user = current_user
# params[:user] => {name: "bob", email: "bob@example.com"}
user.update(user_params)
end
private
# 外部から渡されたパラメーターをそのまま使用せずに
# 明示的に許可したキーのみを利用する
def user_params
params.require(:user).permit(:name, :email)
end
このようにすることでpermitに許可されていないパラメーター、
例えばadmin=trueなどをリクエストに追加したとしても、モデルに渡す際にはadminパラメーターは許可されないので値を不正に
更新されなくなる。
この例では、
user.updateにparams[:user]をそのままではなく、user_paramsメソッドの戻り値を渡している。
そしてuser_paramsメソッドの中ではparamsからモデルの更新に利用しても良いパラメーターを明確にしている。
# この部分が利用しても良いパラメーターを明確化
permit(:name, :email)
user_paramsの内容は以下である
・リクエストにはkeyが必要であること
・userの中で受付が可能なのは[:name,:email]であること
もし、requireに指定したパラメーターがparamsに含まれていなかったら「ActionsController::ParameterMissing」例外が発生する。
StrongParametersの条件を状況によって変更したい場合、
例えば管理権限のあるユーザーであればadmin権限を変更できるようにする
def update
user = current_user
# params[:user] => {name: "bob", email: "bob@example.com"}
user.update(user_params)
end
private
# 外部から渡されたパラメーターをそのまま使用せずに
# 明示的に許可したキーのみを利用する
def user_params
if current_user.admin?
params.require(:user).permit(:name, :email:, :admin)
else
params.require(:user).permit(:name, :email)
end
end
このようにすることで
管理者権限のあるユーザーは自分の権限を変更することができ、
管理者権限のないユーザーは権限を付与することができなくなる。