FormRequestの話はいつも入力値のバリデーションが中心ですが、入力値とは関係ないアクセスのオーソリ(認可)もFormRequest内で設定可能です。その説明のための簡単な例として、登録したユーザーが自分の名前などのプロフィールを編集するするときに、最後の編集から24時間経過しないと次の変更ができない、というのはどうでしょう。
まず、FormRequestをaritisanの実行で作成します。
$ php artisan make:request UserEditRequest
以下のようにオーソリのための関数、authorize()
を定義します。
namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class UserEditRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { $user = auth()->user(); // レコードの更新日と現在の差分を時間で計算 $diff = Carbon::parse($user->updated_at)->diffInHours(Carbon::now()); return ($diff > 24); //差分が24時間超ならOK、そうでないならアクセス不可 } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required', ]; } }
次に、編集画面のコントローラで先のFormRequestを以下のように使用して、
namespace App\Http\Controllers; use App\Http\Requests\UserEditRequest; class UserController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth'); } /** * Show the form for editing the specified resource. * * @return \Illuminate\Http\Response */ public function edit() { $user = auth()->user(); return view('edit'); } /** * Update the specified resource in storage. * * @param \App\Http\Requests\UserEditRequest $request * @return \Illuminate\Http\Response */ public function update(UserEditRequest $request) // ここでFormRequestを使用 { $user = auth()->user(); $user->update($request->validated()); return redirect()->route('home'); } }
過去24時間内にすでにレコードを変更したという仮定で、編集画面の保存ボタンを押すと以下のように403の画面に遷移します。
しかしこれでは、どうしてエラーとなったかユーザーには謎ですね。
拒否された理由のメッセージを表示したいです。
以下のように、FormRequestのfailedAuthorization()
を使えば、
... /** * Handle a failed authorization attempt. * * @return void * * @throws \Illuminate\Auth\Access\AuthorizationException */ protected function failedAuthorization() { throw new AuthorizationException('最後の編集から24時間経過しないと編集可能となりません'); } ...
今度は親切なメッセージのエラー表示となります。
メルマガ購読の申し込みはこちらから。