Laravel 5.8 показывает «419 Page Expired» после нажатия на выход из уже очищенного сеанса

Я запускаю команду php ремесленник сделать: авторизация и шаг за шагом объясню, что я делаю после этого, чтобы понять сценарий,

  • Войдите в новую сессию (example.com/home)
  • открыл новую вкладку и вставил URL, например, example.com/home.
  • Теперь открыто 2 вкладки с одной и той же сессией.
  • Я нажал «Выйти» на одной из вкладок, и все работает отлично.
  • Затем, когда я попытался выйти из системы с другой вкладки, мне выдается сообщение об ошибке «419 Page Expired», и он никуда не уходит даже после перезагрузки.

Дело в том, что могут возникать такие сценарии, и я не хочу видеть это сообщение об ошибке, просто выйдите из системы после нажатия кнопки «Выйти», даже если срок действия сеанса истек.

Примечание. Эта проблема возникает не из-за того, что @csrf не добавлен.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
14
0
21 930
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

Что ж, это очевидное сообщение, которое вы, возможно, можете попытаться улучшить для этой страницы, но все же хорошо показать его, чтобы пользователь знал, что произошло. Если вы хотите сделать это по-другому, вы можете попробовать перенаправить на страницу входа.

Итак, в вашем файле app\Exceptions\Handler.php в методе рендеринга добавьте следующее:

if ($exception instanceof \Illuminate\Session\TokenMismatchException) {
    return redirect()->route('login');
}

Привет, это работает, Танск! Но когда я пытаюсь использовать мультиаутентификацию, сценарий 419 страница не найдена в сеансе администратора, перенаправляющий мой URL-адрес входа администратора на этот (redirect()->route('login')) (т.е. на логин пользователя)

Sobin Augustine 18.07.2019 15:14

Затем перенаправьте на другую страницу, у вас, вероятно, есть одна общая для администраторов и пользователей, которая будет перенаправлять на ту страницу входа, на которую необходимо перенаправить вас.

nakov 18.07.2019 15:17

Да, я получил свое решение, проверю текущий URL-адрес и перенаправлю соответственно. Спасибо за помощь, брат.

Sobin Augustine 18.07.2019 15:24

ИМХО, вы можете попробовать изменить свой файл app/Http/Middleware/VerifyCsrfToken.php. Отредактируйте свойство $кроме примерно так:

class VerifyCsrfToken extends Middleware
{       
    protected $except = [
        'http://example.com/logout',
    ];

Привет, спасибо за ответ.

Sobin Augustine 18.07.2019 15:15

Это полностью отключает защиту csrf для этого маршрута.

halloei 05.11.2020 16:06

очень плохое и небезопасное решение.

Sand Of Vega 06.01.2021 03:52

Это не решение, а всего лишь недостаток безопасности.

Ben Osborne 01.09.2021 20:06
<a href = "{{ route('logout') }}" class = "dropdown-item notify-item" = "event.preventDefault(); document.getElementById('logout-form').submit();">
    <i class = "fa fa-power-off"></i>  <span>{{ __('Logout') }} </span>
    </a>
<form id = "logout-form" action = "{{ route('logout') }}" method = "POST" style = "display: none;">
  @csrf
</form>

Вы пропустили @csrf в форме выхода, поэтому только вы получаете ошибку 419.

Извините, приятель, проблема не в этом, я уже упоминал об этом в своем вопросе.

Sobin Augustine 18.07.2019 15:20

В проекте Laravel 6 я изменил VerifyCsrfTokenMiddleware следующим образом:

Как вы увидите, я просто добавил именованный маршрут logout в список исключений.

Я переопределил функцию __construct, потому что мы не можем использовать функцию route() при инициализации новой переменной.

<?php

namespace App\Http\Middleware;

use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * Indicates whether the XSRF-TOKEN cookie should be set on the response.
     *
     * @var bool
     */
    protected $addHttpCookie = true;

    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [

    ];

    /**
     * Create a new middleware instance.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @param  \Illuminate\Contracts\Encryption\Encrypter  $encrypter
     * @return void
     */
    public function __construct(Application $app, Encrypter $encrypter)
    {
        parent::__construct($app, $encrypter);
        $this->except = [
            route('logout')
        ];
    }
}

Полное удаление токена csrf для выхода из системы является недостатком безопасности и не рекомендуется. Принудительный выход пользователей из системы с помощью атаки csrf может привести к тому, что они раскроют учетные данные для входа в систему, пока они находятся под наблюдением.

Snapey 16.09.2020 01:09

Не могли бы вы указать мне документацию по этой проблеме? и что ты предлагаешь? У меня не может быть жалоб пользователей, потому что они не могут выйти из системы из-за истечения срока действия токена csrf.

realtebo 16.09.2020 15:40

один пример security.stackexchange.com/questions/62769/…

Snapey 16.09.2020 21:14

Я предложил решение в качестве ответа на этот пост. Добавляйте маршрут выхода из системы в правила исключений только в том случае, если срок действия сеанса пользователя уже истек.

Snapey 16.09.2020 21:15

Решение проблемы относительно простое и требует небольшого дополнения к ПО промежуточного слоя VerifyCsrfToken;

use Closure;


    public function handle($request, Closure $next)
    {
        if (!Auth::check() && $request->route()->named('logout')) {
        
            $this->except[] = route('logout');
            
        }
        
        return parent::handle($request, $next);
    }

Обычно этот файл содержит только массив маршрутов $except, которые следует игнорировать из csrf.

В этом коде мы переопределяем метод handle и выполняем две проверки.

  • является ли пользователь гостем (т. е. не использует аутентифицированный сеанс) и,
  • это маршрут выхода из системы

Если оба верны, мы добавляем «выход из системы» в массив исключений. Затем мы передаем управление ядру VerifyCsrfMiddleware, которое распознает наличие маршрута выхода в массиве и обходит проверку. Данные формы размещены правильно, и мы перенаправлены с помощью LogoutResponse.

Пользователь не видит страницы с ошибкой.

Проверяя таким образом, мы гарантируем, что подлинные запросы на выход по-прежнему защищены токеном CSRF.

Ниже use Closer; добавьте use Auth; Для новичков, в проекте Laravel 7 он находится в /app/Http/Middleware/VerifyCsrfToken.php. Ниже приведен полный файл VerifyCsrfToken.php. <?php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; use Closure; use Auth; class VerifyCsrfToken extends Middleware { /** * The URIs that should be excluded from CSRF verification. * * @var array */ protected $except = [ // ]; }

Twelve24 21.10.2020 01:27

У SO есть некоторые странные правила: «Комментарии можно редактировать только в течение 5 минут». Таким образом, в приведенном выше есть некоторые недостающие детали. Ну что ж.

Twelve24 21.10.2020 01:35

да. Подходит для Laravel 7 и 8.

Snapey 09.11.2020 18:07

Вам нужно добавить токен CSRF в форму:

<form action = "{{ route('logout') }}" method = "POST">
    @csrf
    <button type = "submit" class = "btn nav-link">Logout</button>
</form>

Laravel 8.x Документы

Прочтите примечание к вопросу. Примечание. Эта проблема не связана с тем, что @csrf не добавлен.

Sobin Augustine 02.06.2021 21:29

Никогда не поздно)

Добавить приложение/Http/Middleware/VerifyCsrfToken.php

    use Closure;

    public function handle($request, Closure $next)
    {
        if ($request->route()->named('logout')) {
            if (auth()->check()) {
                auth()->logout();
            }

            return redirect('/');
        }
    
        return parent::handle($request, $next);
    }

Я думаю, что это лучшие решения.

Другие вопросы по теме