【Laravel】安全に複数代入するfill($request->validated()) と他の危険な複数代入

 Laravel は web 用のフレームワークです。フレームワークというだけあって色々なことが簡単にできます。
 Eloquent::fill メソッド、 FormRequest::validated メソッドはそういった目的に使われるメソッドです。
 fill メソッドは Eloquent モデル(データベースのテーブルをマッピングしたクラス)に配列でまとめてデータを代入するためのメソッドです。
Eloquent:利用の開始 6.x Laravel

// flight 変数のプロパティの name, delayed に値を代入
$flight->fill([
  'name' => 'Flight 22',
  'delayed' => 1,
]);

 これを使うことでどこからか来た配列に変換可能なまとまったデータをまとめて代入できます。代入可能な値のキーはクラスインスタンスの fillable プロパティないし guards プロパティで決定されます。
 validated メソッドは FormRequest のメソッドの一つでバリデーションを通ったリクエストの値のみを配列で返してくれます。
バリデーション 6.x Laravel

class StoreBlogPost extends FormRequest
{
    /**
     * リクエストに適用するバリデーションルールを取得
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ];
    }
}

class BlogPostController extends Controller
{
    /**
     * ブログポストの保存
     *
     * @param  StoreBlogPost  $request
     * @return Response
     */
    public function store(StoreBlogPost $request)
    {
        // 送信されたリクエストは正しい
    
        // バリデーション済みデータ配列['title' => 何か, 'body' => 何か]の取得
        $validated = $request->validated();
    }
}

 この validate メソッドはバリデーションルールを通過していないリクエストの値を含まない、という点が重要で validated メソッドを介して得た値は不正な入力を含まない安全な値である、といえます。
 fill と validated を組み合わせることによって安全な保存処理を短いコードで作れます。

class BlogPostController extends Controller
{
    /**
     * ブログポストの保存
     *
     * @param  StoreBlogPost  $request
     * @return Response
     */
    public function store(StoreBlogPost $request)
    {
        // 送信されたリクエストは正しい
    
        // バリデーション済みデータ配列['title' => 何か, 'body' => 何か]の取得
        $validated = $request->validated();
        $blogPost  = new BlogPost();
        // fill でバリデーション済みデータをまとめて代入。そのまま保存
        $blogPost->fill($validated)->save();
    }
}

 これに似た挙動であれども危険な書き方が FormRequest::all と Eloquent::forceFill です。
 FormRequest::all はバリデーションを通さず、リクエストされた値全てを通します。このため、動作の想定外である不正な値の代入を許しがちです。
 Eloquent::forceFill は Eloquent の fillable プロパティ、 guards プロパティを無視してまとめて代入を実現するメソッドです。これを使うと更新不可能、ユーザ指定不可能であるべきな値を誤って扱ってしまう事態を引き起こしやすいです。
 片方だけなら、ミスが起こりやすいだけで安全な時もあります。バリデーションなしはプログラムの内容によっては致命傷になります。両方揃っていた場合、データベース中のあるテーブルの INSERT, UPDATE 権限を完全に外部に公開しているようなものです。その様なテーブルに会員種別、権限、の様なプログラムの振る舞いに関する情報が入っていたり、論理削除機能が入っていたりした場合、とてもひどいことをユーザの誰もが起こせます。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG