はじめに
本記事は、プログラミングの学習を始めて1ヶ月の初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。
今回の疑問点
今回の疑問点は、
ストロングパラメーターの使い方について
です。
ストロングパラメーターが必要なタイミングについて疑問を抱きました。
疑問点についての解説
###結論
マスアサインメント機能を使用した場合にストロングパラメーターの記述が必要。特定のカラムやデータを明示してパラメーターを受け取る場合などには記述する必要はない。
###ストロングパラメーターとは
ストロングパラメーターとは、Mass Assignment脆弱性の対策として、開発者が指定したキーを持つパラメーターのみを受け取れるように制限するものです。指定していないキーを持つパラメーターをエラーとして弾くことができます。
###パラメーターとは
パラメーターとは、リクエストに含まれて外部から渡されるデータ、情報のことです。
###Mass Assignment脆弱性とは
Mass Assignment脆弱性とは、悪意あるユーザーにより、Webブラウザ上において手作業などでパラメータを書き換えられ、開発者の意図しないデータの登録・更新(例えば、管理者を識別するためのカラム内データの改竄など)が行われてしまう脆弱性です。
###マスアサインメント機能とは
マスアサインメント機能とは、フォームから送られてきたパラメーターをまとめて保存することができる機能です。とても便利なように見えますが、悪意あるユーザーにより、フォームから送られてきたデータの中に保存したくないパラメーター属性を含められてしまうと、そのまま保存されてしまう危険性があります。この機能が上記の脆弱性につながります。
###ストロングパラメーターの使い所
ストロングパラメーターは上述の通り、Mass Assignment脆弱性の対策のために使用します。Mass Assignment脆弱性はマスアサインメント機能が原因で生じるものであるため、ストロングパラメーターは、マスアサインメント機能を使用したときにのみ記述し、特定のカラム等を明示する場合などには記述する必要はありません。
具体例は以下の通りです。
User.create(params[:user])
上記の場合には、送られてきたパラメーターの内、user
に紐づくものをまとめて受け取っているため、ストロングパラメーターの定義が必要です。
User.create(name: params[:name], email: params[:email])
上記の場合には、カラムと入力データを指定しているため、ストロングパラメーターの定義は不要です。
###ストロングパラメーターの記述方法
ストロングパラメーターは以下のようにprivate以下に記述します。
※private
以下に記述したメソッドは、そのクラスの外からのアクセスができません。クラス外部から呼び出したくないメソッドの隔離、可読性の観点から使用されます。
private
def user_params
# params.require(:キー(モデル名)).permit(:カラム名1,:カラム名2,・・・).merge(カラム名: 入力データ)
params.require(:user).permit(:name,:email).merge(user_id: current_user.id)
end
上記の記述について詳解します。
params
:フォームから送られてきたパラメーターをハッシュ構造で格納している箱のようなもの。
require
:指定したキーに紐づいたparams
内の値だけを抽出する(form_withメソッドで指定したモデル名を指定)。
permit
:requireで抽出したキーの中から、さらに取得したいキー(特定のカラム)を指定する。
merge
:ハッシュ同士を結合する。paramsに含まれない値(外部キー等)をストロングパラメーターに加えたい場合などに記述。
上記の例では、
フォームから送られてきたパラメーターの内、Userモデルの、nameカラム及びemailカラムに対するデータの受け取り、user_idカラムに対するcurrent_user.idのみ受け取りを許可する
という内容となっています。
ストロングパラメーターを定義したら、createアクション等の中で呼び出して使用します。
まとめ
最後にポイントをまとめます。
- ストロングパラメーターは、マスアサインメント機能により生じるMass Assignment脆弱性の対策として使用されるため、マスアサインメント機能を使用する際に記述する
- ストロングパラメーターは
pravate
以下にparams.require(:キー(モデル名)).permit(:カラム名1,:カラム名2,・・・).merge(カラム名: 入力データ)
の形で記述する