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時間経過しないと編集可能となりません');
}
...
今度は親切なメッセージのエラー表示となります。
メルマガ購読の申し込みはこちらから。

