自学-堅牢なシステム設計(Rails)

Ruby on Rails6実践ガイド(RoR中級者本)を自学したので内容を書く。
  1. Strong Parameters
  2. model見るときのvalidates inclution {%w}...について




①Strong Parameters
  • Strong Parametersとは、マスアサインメント脆弱性と呼ばれるセキュリティホール対策としてRailsが用意している仕組み
  • モデルオブジェクトのassign_attributesメソッドは、引数にハッシュかparamsオブジェクトをとって、モデルオブジェクトの属性を一括変更する。
  • ここで、書き換えられては困る属性値(hashed_password)を悪意あるユーザーに変更されるリスクが存在する
  • これらのWebアプリの脆弱性をマスアサインメント脆弱性と呼ぶ
  • これに対して、Strong Parametersという仕組みがRails4.0で導入された
[実装①]
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

Next Post Previous Post
No Comment
Add Comment
comment url