Вопрос или проблема
У меня есть фронтенд на React, работающий на порту 5173, и бэкенд на Node.js на порту 5000. У меня есть форма входа, которая выполняет вход, и в ответе есть заголовок set-cookie с токеном. Однако файл cookie не отображается в инструментах разработчика в разделе Приложение->Хранилище->Файлы cookie, и его также нет в последующих запросах.
Настройка CORS
app.use(cors({
origin: 'http://localhost:5173',
credentials: true,
}));
Создание файлов cookie
res.cookie('token', authToken.token, {
httpOnly: false,//false только для тестирования
secure:false,
sameSite: 'None',
maxAge: 1000 * 60 * 60 * 168, // 1 неделя
path: "https://stackoverflow.com/"
})
Вызов на фронтенде после входа
const response = await fetch('http://localhost:5000/api/auth/check', {
method: 'GET',
credentials: 'include',
});
Проверка наличия файла cookie в запросе
console.log(req.cookies);
Результат – [Object: null prototype] {}
Я чувствую, что проблема должна быть в самом начале, так как файл cookie не отображается в инструментах разработчика, но я не уверен, почему, так как он есть в ответе. Вот ответ после вызова функции входа
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:5173
Vary: Origin
Access-Control-Allow-Credentials: true
Set-Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ODMyMjMzNjk0LCJhY2Nlc3MiOjEsImlhdCI6MTcyODE0NDE2NiwiZXhwIjoxNzI4NzQ4OTY2fQ.F83l7VGYvZLcYXY6gaFQmezd9TuCIDQIv0JRySaA9qI; Max-Age=604800; Path=/; Expires=Sat, 12 Oct 2024 16:02:46 GMT; SameSite=None
Content-Type: application/json; charset=utf-8
Content-Length: 43
ETag: W/"2b-L/lj66ZG7Ci3fY6guTi0ymZXOqc"
Date: Sat, 05 Oct 2024 16:02:46 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Я пытался изменить настройки CORS и параметры файлов cookie, но все равно ничего не получается. Заголовок set-cookie есть в ответе, но он не идет дальше. Я видел другие вопросы по этой теме и считаю, что попробовал все, но, возможно, я исправлял одну проблему и ломал что-то другое.
Ответ или решение
Проблема, с которой вы столкнулись, связана с тем, что куки не сохраняются в браузере и, соответственно, не отправляются при последующих запросах к вашему серверу. Давайте разберем несколько аспектов, которые могут повлиять на это, и предложу вам возможные решения.
1. Настройки CORS
Ваши настройки CORS выглядят почти правильно, но убедитесь, что использование credentials: true
как на стороне сервера, так и на стороне клиента установлено правильно. Вы уже указали credentials: true
в CORS на сервере, далее убедитесь, что вы используете credentials: 'include'
при вызове fetch
на стороне клиента, что вы уже сделали.
2. Параметры куки
Обратите внимание на параметры, которые вы передаете при создании куки:
res.cookie('token', authToken.token, {
httpOnly: false, // как для теста, но лучше оставить true для безопасности
secure: false, // должно быть true, если вы работаете через HTTPS
sameSite: 'None', // для работы с CORS должно быть 'None', но с secure: true для безопасности
maxAge: 1000 * 60 * 60 * 168, // 1 неделя
path: '/' // путь должен быть '/', чтобы куки могли быть доступны для всех маршрутов
});
3. Путь куки
Есть момент, который следует обратить внимание — path
в вашем res.cookie
. Убедитесь, что path
установлен в '/'
, чтобы куки были доступны для всех маршрутов вашего приложения, а не только для конкретного пути. Убедитесь, что у вас установлен правильный путь для хранения куки.
4. Убедитесь, что браузер поддерживает куки
Некоторые браузеры имеют дополнительные настройки безопасности, которые могут блокировать куки, особенно при использовании SameSite=None
без Secure
. Убедитесь, что вы проверяете это в браузере, который не блокирует куки.
5. Проверка ответа сервера
Проверьте, что ваша серверная часть действительно отправляет ‘Set-Cookie’ в ответе. Вы уже предоставили часть ответа, и он выглядит правильным. Убедитесь, что это происходит каждый раз, когда вы выполняете вход, и что есть не только правильный заголовок, но и статус ответа 200.
6. Консоль разработчика
Откройте инструменты разработчика в вашем браузере, перейдите во вкладку «Сеть» и выполните повторный запрос. Найдите ответ с заголовком Set-Cookie
и проверьте, нет ли в консоли ошибок, связанных с установкой куки. Это может помочь вам найти возможные ошибки конфигурации.
Пример
Вот более полный пример, который должен включать все вышеуказанные изменения:
app.use(cors({
origin: 'http://localhost:5173',
credentials: true
}));
app.post('/api/auth/login', (req, res) => {
const authToken = { token: 'your_jwt_token_here' };
res.cookie('token', authToken.token, {
httpOnly: true,
secure: false, // Установить true при использовании HTTPS
sameSite: 'None',
maxAge: 1000 * 60 * 60 * 168, // 1 неделя
path: '/'
});
res.status(200).json({ message: 'Login successful' });
});
И не забудьте в клиентском коде указывать credentials: 'include'
:
const response = await fetch('http://localhost:5000/api/auth/check', {
method: 'GET',
credentials: 'include',
});
Если все вышеперечисленное было проверено и исправлено, но проблема все еще существует, рекомендуется протестировать на другом браузере или с отключенным кэшем, так как иногда старые настройки кэша могут вызывать проблемы.