自学-堅牢なシステム設計(Rails)
Ruby on Rails6実践ガイド(RoR中級者本)を自学したので内容を書く。
- Strong Parameters
- model見るときのvalidates inclution {%w}...について
■
■
①Strong Parameters
[リクエストのテスト]
■
①Strong Parameters
- Strong Parametersとは、マスアサインメント脆弱性と呼ばれるセキュリティホール対策としてRailsが用意している仕組み
- モデルオブジェクトのassign_attributesメソッドは、引数にハッシュかparamsオブジェクトをとって、モデルオブジェクトの属性を一括変更する。
- ここで、書き換えられては困る属性値(hashed_password)を悪意あるユーザーに変更されるリスクが存在する
- これらのWebアプリの脆弱性をマスアサインメント脆弱性と呼ぶ
- これに対して、Strong Parametersという仕組みがRails4.0で導入された
[実装①]
sessions_controllerに埋める
sessions_controllerに埋める
private def login_form_params
params.require(:admin_login_form).permit(:email, :password)
end
- クライアントの送信したデータから不必要なパラメータを除去する
- Parametersオブジェクトが、admin_login_formをもち,email/passwordがあるか
private def staff_member_params
params.require(:staff_member).permit(
:email, :password, :family_name,given_name,
:family_name_kana, :given_name_kana,
:start_date, :end_date, :suspended
)
end
[リクエストのテスト]
require "rails_helper"
describe "職員管理" do
let(:administrator) {create(:administrator)}
describe "新規登録" do
let(:params_hash) {attributes_for(:staff_member)}
end
describe "更新" do
let(:staff_member) {create(:staff_member)}
let(:params_hash) {attributes_for(:staff_member)}
end
end
- attributes_forメソッドはFactorybotが提供するメソッド
- config.include FactoryBot::Syntax::Methodsをspec/rails_helper.rbに追加
- 引数にファクトリーの名前をとって、戻り値にハッシュを返す
- そのハッシュはそのままモデルオブジェクトのassign_attributesメソッドの引数に使えるキーと値を持つ
- letメソッドはシンボルを引数に取り、必ずブロックを引き連れる
- letは「メモ化されたヘルパーメソッド」を定義するメソッド
- 複数回呼び出された際の挙動が特徴的である
- ①回目の呼び出しでは普通にメソッドを実行する。同時に結果を記憶する
- ②回目以降の呼び出しでは一回目の結果をそのまま返す
example "一覧にリダイレクト" do
post admin_staff_members_url, params: {staff_member: params_hash}
expect(response).to redirect_to(admin_staff_members_url)
end
exampel "例外ActionController::ParameterMissing" do
expect { post admin_staff_members_url }.to raise_error(例外ActionController::ParameterMissing)
end
- postは、コントローラーのspec特有
- 第一引数に指定したメソッドに、第二引数のデータをPOSTで送信する
- RSpecの内部で模擬的なHTTPリクエストを行っている
- responseはActionController::TestResponceオブジェクトを返す
- このオブジェクトはアクションの実行結果を保持している
- redirect_toは引数に指定したurlへのリダイレクションの検証
- raise_error()は特定のエラーを排出する
updateアクションのexampleを書く
example "suspendflgをセットする" do
params_hash.merge!(suspended: true)
patch admin_staff_members_url(staff_member),
params_hash: {staff_member: params_hash}
staff_member.reload
expect(staff_member).to be_suspended
end
example "hashed_passwordの値は下記かえ不可" do
params_hash.delete(:password)
params_hash.merge!(hashed_password: "x")
expect {
patch admin_staff_members_url(staff_member),
params: {staff_member: params_hash}
}.not_to change {staff_member.hashed_password.to_s}
end
- あ