#nuxtjs #laravel-sanctum
#nuxtjs #laravel-sanctum
Вопрос:
Я использую Laravel 8 и пытаюсь следовать документации sanctum для аутентификации SPA. Я уже настроил необходимые конфигурации. Внутренний сервер работает на localhost с портом по умолчанию (80), в то время как SPA-клиент работает на localhost: 3000. Я использую nuxt framework для клиента с axios, чтобы сделать запрос.
Первоначальный запрос должен быть сделан в /sanctum/csrf-cookie для инициализации защитного файла cookie CSRF, и вот что показывает трафик сетевого трафика
Второй запрос — это фактический запрос, который должен содержать файлы cookie, отправленные первым запросом для домена, но похоже, что XSRF-ТОКЕН пропускается. Вот как выглядит сетевой трафик
sanctum.php конфигурационный файл:
<?php
return [
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1'
)),
'expiration' => null,
'middleware' => [
'verify_csrf_token' => AppHttpMiddlewareVerifyCsrfToken::class,
'encrypt_cookies' => AppHttpMiddlewareEncryptCookies::class,
],
];
cors.php конфигурационный файл:
<?php
return [
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*', 'localhost:3000'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => ['XSRF-TOKEN', 'X-XSRF-TOKEN'],
'max_age' => 0,
'supports_credentials' => true,
];
session.php конфигурационный файл
<?php
use IlluminateSupportStr;
return [
'driver' => env('SESSION_DRIVER', 'file'),
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => env('SESSION_CONNECTION', null),
'table' => 'sessions',
'store' => env('SESSION_STORE', null),
'lottery' => [2, 100],
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
'path' => '/',
'domain' => env('SESSION_DOMAIN', null),
'secure' => env('SESSION_SECURE_COOKIE'),
'http_only' => true,
'same_site' => 'lax',
];
Я установил это в nuxt.config.js
export default {
axios: {
withCredentials: true,
baseURL: 'http://localhost/',
},
}
Может кто-нибудь сказать мне, почему файл cookie XSRF-ТОКЕНА не отправляется обратно?
Спасибо
Комментарии:
1. Пока нет ответов, можете ли вы поделиться дополнительной информацией? cors.php и session.php было бы полезно.
Ответ №1:
Оказывается, проблема была вызвана конфигурацией nuxt для модуля axios. Я просто заменил поле ‘withCredentials’ на просто ‘учетные данные’.
Теперь это обновленный nuxt.config.js:
axios: {
credentials: true,
baseURL: 'http://localhost/api/',
},
Ответ №2:
Вот моя конфигурация Nuxt / Laravel 8 / Sanctum.
Обратите внимание, что я не включил 'sanctum/csrf-cookie'
в 'paths'
, потому что я изменил префикс для Sanctum в sanctum.php
. У меня также есть сервер разработки nuxt на порту 3050, который вы увидите в моей конфигурации. Измените свой на подходящий (например, 3000).
cors.php
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => [env('ALLOWED_ORIGINS')],
.env e.g.: ALLOWED_ORIGINS=http://localhost:3050
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
Все в session.php остается по умолчанию, но убедитесь, что вы обновили свой файл .env правильным SESSION_DOMAIN
.
session.php
'driver' => env('SESSION_DRIVER', 'file'),
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => env('SESSION_CONNECTION', null),
'table' => 'sessions',
'store' => env('SESSION_STORE', null),
'lottery' => [2, 100],
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
'path' => '/',
'domain' => env('SESSION_DOMAIN', null),
.env e.g.: SESSION_DOMAIN=localhost
'secure' => env('SESSION_SECURE_COOKIE'),
'http_only' => true,
'same_site' => 'lax',
Все в sanctum.php по умолчанию, убедитесь, что вы ввели правильное SANCTUM_STATEFUL_DOMAIN
значение в свой файл .env (пример ниже). Я также добавил строку 'prefix' => 'api'
. Это позволяет мне установить один baseUrl в axios и вызвать csrf-cookie
маршрут через http://localhost:3050/api/csrf-cookie
. Подробнее об этом здесь .
sanctum.php
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
.env e.g.: SANCTUM_STATEFUL_DOMAINS=localhost:3050
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1'
)),
'expiration' => null,
'middleware' => [
'verify_csrf_token' => AppHttpMiddlewareVerifyCsrfToken::class,
'encrypt_cookies' => AppHttpMiddlewareEncryptCookies::class,
],
'prefix' => 'api'
Затем во внешнем интерфейсе я установил axios с помощью baseUrl и убедился withCredentials
, что для него установлено значение true
axios.defaults.withCredentials = true;
axios.defaults.baseURL = process.env.API_BASE_URL;
.env e.g.: API_BASE_URL=http://localhost:8000/api
Предполагая, что вы не внесли никаких других изменений, которые противоречат приведенным выше настройкам, это должно сработать 🙂
Ответ №3:
Если вы следовали этим инструкциям, и у вас все еще возникают проблемы, как и у меня, возможно, вы пропустили настройку SESSION_DOMAIN
в своем файле .env.
Откройте файл Laravel .env и добавьте SESSION_DOMAIN=.localhost
Еще одна вещь: если вы по какой-то причине не можете получить доступ к маршруту «/ csrf-cookie» и вам все равно нужно вызвать «sanctum / csrf-cookie /», но Axios добавляет /api
перед вашими запросами, тогда используйте этот фрагмент кода:
let myNewInstance = this.$axios.create({
baseURL: 'http://localhost' //without /api at the end
});
myNewInstance.get('/sanctum/csrf-cookie');
Ответ №4:
Возможно, ваше приложение laravel работает на 127.0.0.1: 8000, а ваш SPA работает на localhost: 3000 или localhost: 8080 и т.д.
Убедитесь, что вы:
- Установите для домена сеанса значение localhost
- Установите значение
supports_credentials
true
(cors.php ) - Установите
with_credentials
значениеtrue
в вашем клиенте - Когда вы отправляете запросы на свой серверный сервер, отправляйте его на localhost: 8000 вместо 127.0.0.1: 8000