Я использую Laravel 9.41.0 и PHP 8.1. Когда время ожидания сеанса Laravel по умолчанию истекает, доступ к любым защищенным маршрутам после этого вызывает это исключение. Laravel не перенаправляет на маршрут входа в систему, который я уже определил. Исключение возникает в промежуточном программном обеспечении VerifyCsrfToken
. Вот метод, в котором возникает исключение:
C:\wamp-new\www\twicterminal.com\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken
.php : 191
/**
* Add the CSRF token to the response cookies.
*
* @param \Illuminate\Http\Request $request
* @param \Symfony\Component\HttpFoundation\Response $response
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function addCookieToResponse($request, $response)
{
$config = config('session');
if ($response instanceof Responsable) {
$response = $response->toResponse($request);
}
$response->headers->setCookie($this->newCookie($request, $config));
return $response;
}
Эта строка в методе: $response->headers->setCookie($this->newCookie($request, $config));
— источник исключения.
Я много гуглил эту проблему, но пока не нашел рабочего решения. Здесь, в StackOverflow, есть похожие вопросы, их сценарии, происхождение и варианты использования разные. Их решения мне тоже не подошли.
Примечание. Это исключение возникает только для маршрутов, защищенных промежуточным программным обеспечением по умолчанию, после истечения времени ожидания сеанса по умолчанию.
Привет @lagbox, у меня нет специального промежуточного программного обеспечения на этих маршрутах, и я не модифицировал какое-либо существующее промежуточное программное обеспечение, поставляемое с Laravel.
Из любопытства, не могли бы вы дать ссылку на аналогичные вопросы, которые вы упомянули? Я сейчас работаю над похожей проблемой. Ваша проблема в том, что при вызове $response->headers->setCookie(...)
$response
равно нулю. У меня возникает эта проблема, и у меня возникают проблемы с тем, что $response
является нулевым в другом месте промежуточного программного обеспечения Laravel.
Для каждого класса в вашей папке app/Http/Middleware
проверьте каждый метод handle
и убедитесь, что каждый из них всегда возвращает экземпляр \Illuminate\Http\Response
. Вы сказали, что у вас нет собственного промежуточного программного обеспечения и вы не изменяли ни один из классов промежуточного программного обеспечения, которые вам предоставил Laravel. Проверьте их внимательно. Где-то вы получаете нулевую переменную $response
, которая должна быть экземпляром \Illuminate\Http\Response
. Наиболее вероятной причиной является метод handle
, который не возвращает значение напрямую (таким образом, возвращает ноль).
Всем спасибо. Я люблю сообщество, и это удивительно помогать друг другу.
Я провел обширный поиск, и ни одно из решений не сработало для меня. К счастью, я решил проблему самостоятельно, но забыл добавить ответ здесь. Раньше я изменил класс Laravel по умолчанию Handler
(для обработки исключений) и добавил этот метод для запроса API без аутентификации. Он отлично работал для вызовов API, но с веб-запросами возникали проблемы. Вот метод:
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return $this->response('User not authenticated. Access denied.', Response::HTTP_FORBIDDEN);
}
}
Что я забыл добавить, так это эту строку в конце метода, и это было причиной того, что объект $response
был нулевым. Теперь он работает нормально.
return redirect()->guest($exception->redirectTo() ?? route('login'));
PS: - Позже я нашел более элегантное решение. Что-то, что было «способом Laravel» делать вещи. Я вызвал метод renderable
класса исключения внутри метода register класса Handler
и поймал исключение AuthenticationException
. Вот посмотрите:
$this->renderable(function (AuthenticationException $e, $request) {
if ($request->is('api/*')) {
return $this->response("User not authenticated. Access denied.",
Response::HTTP_FORBIDDEN);
}
return redirect()->guest($e->redirectTo() ?? route('login'));
});
у вас также есть специальное промежуточное ПО для этих маршрутов или вы изменили какое-либо промежуточное ПО по умолчанию?