Laravel 8, Sanctum, Fortify /logout выдает «несоответствие токена CSRF» в Postman

Я установил L8, Sanctum и Fortify для аутентификации. я мог /login (использовал Pre-request Script установить X-XSRF-TOKEN). Я даже получаю /api/userуспешно. Но когда я это делаю, я получаю ошибку «Несоответствие токена CSRF» в Postman. Мои настройки в файлах следующие:

.env

      SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8000

cors.php

      'paths' => ['api/*', 'login', 'logout', 'register', 'sanctum/csrf-cookie']

fortify.php

      'views' => false

/app/Http/Kernel.php

      'api' => [
  \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
  'throttle:api',
  \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

Я не использовал HasApiTokens черта в User модель, поскольку это аутентификация на основе файлов cookie.

В Postman я использую следующие заголовки для /logout маршрут:

      Accept:application/json
Referer:localhost:8000
X-XSRF-TOKEN:{{xsrf-token}}

и я делаю POST просьба к http://localhost:8000/logout. Почему я получаю сообщение об ошибке «Несоответствие токена CSRF»?

3 ответа

Я не уверен, что вы когда-нибудь решали эту проблему, но если нет, мне просто пришлось решить ту же проблему.

Причина сбоя заключается в том, что токен CSRF обновляется для каждого запроса, поэтому вам необходимо добавить сценарий пост-запроса в свой запрос на вход (и любые другие запросы, которые вы делаете).

например, вы можете добавить скрипт в раздел «Тесты» запроса:

      postman.setEnvironmentVariable("xsrf-token", postman.getResponseCookie("XSRF-TOKEN").value);
tests["CSRF token updated"] = true;

Вторая строка предназначена для того, чтобы сценарий не сообщал о сбое каждый раз.

Я также обнаружил, что может потребоваться использовать decodeURIComponent() от стоимости токена.

В твоей App\Http\Middleware\VerifyCsrfTokenпромежуточное ПО, добавить /api/logoutк $exceptмножество:

      protected $except = [
    '/api/logout'
];

Пакеты поставщиков также используют (SESSION_DOMAINиSANCTUM_STATEFUL_DOMAINS), поэтому иногда наблюдается странное поведение.

Удалите их из списка, если они есть.

      # SESSION_DOMAIN=
# SANCTUM_STATEFUL_DOMAINS=

Добавьте их в.env. Убедитесь, что URL указан полностью (схема, домен и порт (в разработке))

      APP_URL=http://localhost:8000

FRONTEND_URLS=http://localhost:5173,http://localhost:5174,http://localhost:5175,http://localhost:5176

Добавьте их вconfig/cors.php

      return [
    'paths' => ['*'],

    'allowed_methods' => ['*'],

    'allowed_origins' => explode(',', env('FRONTEND_URLS')),

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,
]

Добавьте их вconfig/sanctum.php

      return [
...
'stateful' => explode(
        ',',
        env(
            'SANCTUM_STATEFUL_DOMAINS',
            sprintf(
                '%s%s%s',
                'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
                env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : '',
                env('FRONTEND_URLS')
                    ? implode(
                        ',',
                        array_map(function ($url) {
                            return parse_url($url, PHP_URL_HOST);
                        }, explode(',', env('FRONTEND_URLS')))
                    )
                    : ''
            )
        )
    ),
...
]

Убедитесь, что эта строка присутствует вkernel.php

       protected $middlewareGroups = [
        'web' => [
            ...
        ],

        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, // <---
          ...
        ],
    ];

Затем не забудьте очистить кеш как в разработке, так и на сервере.

      php artisan config:clear
php artisan route:clear
php artisan cache:clear
Другие вопросы по тегам