Интерфейс 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

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