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