Интерфейс vue-cli не устанавливает файл cookie CSRF из Sanctum
Я разрабатываю новый интерфейс, используя Vue для доступа к моему существующему приложению Laravel 7, которое использует Sanctum для аутентификации.
Интерфейс находится на app.example.com, а серверная часть перемещается на api.example.com. ПО промежуточного слоя CORS и Sanctum правильно настроены, чтобы разрешить app.example.com, и пока все в порядке.
ПОЛУЧИТЬ /sanctum/csrf-cookie
выглядит нормально, однако, похоже, что на самом деле файлы cookie не устанавливаются, в результате чего последующий запрос к API возвращает 419.
const config = { withCredentials: true };
const api = process.env.NODE_ENV === 'production' ? 'https://api.example.com' : 'http://localhost:9000';
axios.get(api + '/sanctum/csrf-cookie', config)
.then(() => axios.post(api + '/login', data, config))
.then(response => response.json())
.then(response => { console.log('json', response); });
Журнал консоли:
Заголовки ответа от / sanctum / csrf-cookie:
В инструментах разработки нет файлов cookie:
ОБНОВЛЕНИЕ 1: не заметил этого раньше; значки предупреждений рядом с каждымSet-Cookie
в заголовках ответа отображается "Атрибут домена этого set-cookie недопустим по отношению к текущему URL-адресу хоста".
2 ответа
Краткий ответ: не следует указывать порты в атрибутах домена cookie.
Длинный ответ: Laravel Sanctum используетVerifyCsrfToken
промежуточное ПО для отправки и проверки токена CSRF, который использует значения конфигурации сеанса при добавлении cookie в ответ:
protected function addCookieToResponse($request, $response)
{
$config = config('session');
if ($response instanceof Responsable) {
$response = $response->toResponse($request);
}
$response->headers->setCookie(
new Cookie(
'XSRF-TOKEN', $request->session()->token(), $this->availableAt(60 * $config['lifetime']),
$config['path'], $config['domain'], $config['secure'], false, false, $config['same_site'] ?? null
)
);
return $response;
}
В config/session.php
:
'domain' => env('SESSION_DOMAIN', null),
В .env
:
SESSION_DOMAIN=localhost:8080
Файлы cookie на одном и том же хосте НЕ различаются портами. Поскольку я указал порт в домене cookie, браузер пометил cookie как недействительный домен. Удаление порта сделало свое дело.
Чтобы решить эту проблему, я изменил свой хост vue cli, который был 127.0.0.1:8080, на localhost:8080 в браузере, а в axios базовый URL-адрес теперь http://localhost:7000, который предназначен для laravel API.
после этого я устанавливаю SESSION_DOMAIN=localhost в .env laravel