Исключение TokenMismatchException
Исключение TokenMismatchException относится к группе HTTP-исключений
Laravel и возникает, когда CSRF-токен, переданный в запросе, не соответствует
токену, хранящемуся в сессии пользователя. Это стандартный механизм защиты
от межсайтовой подделки запросов (CSRF). Исключение генерируется
внутри промежуточного слоя VerifyCsrfToken при обработке
POST, PUT, DELETE и PATCH запросов.
Синтаксис
<?php
// Проверка CSRF-токена происходит автоматически
// через middleware VerifyCsrfToken
throw new TokenMismatchException();
?>
Причины возникновения
Основные причины возникновения исключения:
<?php
// 1. Истек срок действия сессии
// 2. Неправильно передан CSRF-токен в форме
// 3. Несовпадение токена в сессии и запросе
// 4. Отключен или неправильно настроен механизм сессий
?>
Пример с формой
Рассмотрим типичный пример возникновения исключения при отправке формы без CSRF-токена:
<form method="POST" action="/submit">
<!-- Забыли добавить @csrf -->
<input type="text" name="name">
<button type="submit">Submit</button>
</form>
<?php
use Illuminate\Support\Facades\Route;
Route::post('/submit', function () {
return "Form submitted successfully";
});
?>
При отправке такой формы будет выброшено исключение:
"TokenMismatchException in VerifyCsrfToken.php"
Правильное использование CSRF-токена
Чтобы избежать исключения, необходимо добавлять CSRF-токен в каждую форму:
<form method="POST" action="/submit">
@csrf
<input type="text" name="name">
<button type="submit">Submit</button>
</form>
Результат выполнения кода после добавления токена:
"Form submitted successfully"
Исключение для отдельных маршрутов
Иногда необходимо исключить определённые маршруты из проверки CSRF. Например, для внешних API-запросов:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
protected $except = [
'/webhook/*',
'/api/external/*',
];
}
?>
Теперь запросы к маршрутам, начинающимся с /webhook/
или /api/external/, не будут проверять CSRF-токен.
Обработка исключения
Исключение можно обработать в обработчике ошибок для отображения понятного сообщения:
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Session\TokenMismatchException;
use Throwable;
class Handler extends ExceptionHandler
{
public function render($request, Throwable $exception)
{
if ($exception instanceof TokenMismatchException) {
return redirect()->back()
->withErrors(['csrf' => 'Session expired. Please try again.']);
}
return parent::render($request, $exception);
}
}
?>
Результат выполнения кода при возникновении исключения:
"Redirect back with error message: Session expired. Please try again."
Смотрите также
-
исключение
HttpException,
базовое исключение для всех HTTP-ошибок -
исключение
NotFoundHttpException,
возникает при обращении к несуществующему маршруту -
исключение
MethodNotAllowedHttpException,
возникает при использовании неверного HTTP-метода -
класс
Handler,
главный обработчик всех исключений в приложении