はじめに
viewに@csrfが入っていないから発生するって記事が多すぎ…
入れていてもセッション切れで発生するし、こんなページが表示されてもユーザー(利用者)はどうすればよいかわからない。
419エラー画面にログイン画面へ遷移するリンクを付けるとか、
強制的気にログイン画面へ遷移するかぐらいが利用者はわかりやすいかと思う。
そもそもcsrfってなんやねん
原因
- そもそも@csrfがviewにない。
- セッションが切れて(or csrfを改ざんして)POSTした。
この2パターンかなと。厳密に言ったらもっとあるんやろうけど。
@csrfがviewにない場合
viewに@csrfを入れましょう。
<form method="POST" action="{{ route('login') }}">
@csrf // この行を入れましょう!
:
:
</form>
セッション切れ or csrf改ざん
419エラー画面をカスタマイズ
まずは、Laravel側のエラー画面をコピーする。
% php artisan vendor:publish --tag=laravel-errors
Copied Directory [/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views] To [/resources/views/errors]
Publishing complete.
こんな感じでファイルが出来上がる。
/resources/views/errors
├── 401.blade.php
├── 403.blade.php
├── 404.blade.php
├── 419.blade.php
├── 429.blade.php
├── 500.blade.php
├── 503.blade.php
├── illustrated-layout.blade.php
├── layout.blade.php
└── minimal.blade.php
401〜503は、minimal.blade.phpを参照しているので、こいつにログイン画面への遷移を追加してあげればよいかと思う。
<body class="antialiased">
<div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center sm:pt-0">
<div class="max-w-xl mx-auto sm:px-6 lg:px-8">
<div class="flex items-center pt-8 sm:justify-start sm:pt-0">
<div class="px-4 text-lg text-gray-500 border-r border-gray-400 tracking-wider">
@yield('code')
</div>
<div class="ml-4 text-lg text-gray-500 uppercase tracking-wider">
@yield('message')
</div>
</div>
<!-- このブロックを追加 -->
<div class="flex items-center pt-8 sm:justify-start sm:pt-0">
<div class="px-4 text-lg text-gray-500 border-gray-400 tracking-wider">
<a href="{{ route('login') }}">ログイン</a>
</div>
</div>
</div>
</div>
</body>
ログインへリダイレクト
こんなエラー画面を利用者に見せる必要はないと思ってる。だからログインへリダイレクトすればいいんじゃない?
app/Exceptions/Handler.php
use Illuminate\Session\TokenMismatchException; // 追加
class Handler extends ExceptionHandler
{
:
:
:
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Throwable $exception)
{
// Tokenエラーの時、ログイン画面にリダイレクトする。
if ($exception instanceof TokenMismatchException) {
return redirect(route('login'));
}
return parent::render($request, $exception);
}
:
:
:
まとめ
やりやすいようにやればいいと思う。
コメント