Почему не удается записать токен аутентификации в cookie?

Ссылка скопирована
1 ответ

У меня имеется клиент такого вида:

//store для компонента формы логина    	const login = ref('');    	const password = ref('');    	const isAuthenticated = ref(false);    	const respAuthMessage = ref(null);     	const updateAuthentication = (token) => { // если токен приходит, то меняю тип на boolean     	  isAuthenticated.value = !!token;    	}     	const handleSubmit = async () => {    	  const loginData = {    	    login: login.value,    	    password: password.value    	  }    	  try {    	    const resp = await loginUser(loginData);    	    const token = resp.token;    	    respAuthMessage.value = resp;    	    updateAuthentication(token);    	    if (isAuthenticated.value) {    	      router.push('/');    	    }    	  } catch (error) {    	    console.error('Error:', error);    	  }    	}     	//api.js    	const getData = async (response) => {    	  const data = await response.json();    	  return data;    	}     	async function fetchData(endpoint, requestData) {    	  const requestOptions = {    	    method: 'POST',    	    headers: {    	      'Content-Type': 'application/json'    	    },    	    body: JSON.stringify(requestData),    	  };     	  const response = await fetch(`http://localhost:5000/auth/${endpoint}`, requestOptions);    	  return getData(response)    	}     	export async function loginUser(loginData) {    	  return fetchData('Login', loginData);    	}

//store для компонента формы логина const login = ref(''); const password = ref(''); const isAuthenticated = ref(false); const respAuthMessage = ref(null); const updateAuthentication = (token) => { // если токен приходит, то меняю тип на boolean isAuthenticated.value = !!token; } const handleSubmit = async () => { const loginData = { login: login.value, password: password.value } try { const resp = await loginUser(loginData); const token = resp.token; respAuthMessage.value = resp; updateAuthentication(token); if (isAuthenticated.value) { router.push('/'); } } catch (error) { console.error('Error:', error); } } //api.js const getData = async (response) => { const data = await response.json(); return data; } async function fetchData(endpoint, requestData) { const requestOptions = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestData), }; const response = await fetch(`http://localhost:5000/auth/${endpoint}`, requestOptions); return getData(response) } export async function loginUser(loginData) { return fetchData('Login', loginData); }

так же сервер:

//index.js import express from "express"; import mongoose from "mongoose"; import authRouter from "./authRouter.js"; import cors from 'cors'; import cookieParser from 'cookie-parser';  const PORT = process.env.PORT || 5000; const app = express();  app.use(express.json()); app.use(cors()); app.use(cookieParser());  app.use("/auth", authRouter);   const DB_URL = ...;  const start = async () => {     try {         await mongoose.connect(DB_URL);         app.listen(PORT, () => {             console.log(`${PORT}`);         });     } catch(e) {         console.log(e);     } } start();  //authController.js import bcrypt from 'bcryptjs'; import jwt from 'jsonwebtoken'; import { secret } from '../config.js'  const generateAccessToken = (id, roles) => {     const payload = {         id,         roles,     }     return jwt.sign(payload, secret, { expiresIn: "24h" }) }  class authController { async login(req, res) {   try {     const { login, password } = req.body      const user = await User.findOne({ login })     if(!user) {       return res.status(400).json({ message: `User ${ login } not found` })     }     const validPassword = bcrypt.compareSync(password, user.password)     if(!validPassword) {       return res.status(400).json({ message: `Incorrect password entered` })     }     const token = generateAccessToken(user._id, user.roles)      res.cookie('token', token, { httpOnly: true, maxAge: 3600000 });// не записывает в cookie     return res.json({ token })     }     catch(e) {       console.log(e)       res.status(400).json({message: 'Login error'})      } } }

//index.js import express from "express"; import mongoose from "mongoose"; import authRouter from "./authRouter.js"; import cors from 'cors'; import cookieParser from 'cookie-parser'; const PORT = process.env.PORT || 5000; const app = express(); app.use(express.json()); app.use(cors()); app.use(cookieParser()); app.use("/auth", authRouter); const DB_URL = ...; const start = async () => { try { await mongoose.connect(DB_URL); app.listen(PORT, () => { console.log(`${PORT}`); }); } catch(e) { console.log(e); } } start(); //authController.js import bcrypt from 'bcryptjs'; import jwt from 'jsonwebtoken'; import { secret } from '../config.js' const generateAccessToken = (id, roles) => { const payload = { id, roles, } return jwt.sign(payload, secret, { expiresIn: "24h" }) } class authController { async login(req, res) { try { const { login, password } = req.body const user = await User.findOne({ login }) if(!user) { return res.status(400).json({ message: `User ${ login } not found` }) } const validPassword = bcrypt.compareSync(password, user.password) if(!validPassword) { return res.status(400).json({ message: `Incorrect password entered` }) } const token = generateAccessToken(user._id, user.roles) res.cookie('token', token, { httpOnly: true, maxAge: 3600000 });// не записывает в cookie return res.json({ token }) } catch(e) { console.log(e) res.status(400).json({message: 'Login error'}) } } }

По факту, всё работает хорошо. После регистрации, при логине, я получаю токен, но чего-то он не записывается в cookie. Даже в заголовке ответов в вкладке network я вижу тот самый токен:
Set-Cookie: token=....
Сайт находится на порту 5173, а сервер на 5000. Для корректной работы я использовал cors.

Дополнительно:

Заголовок "Access-Control-Allow-Credentials" выставили?

  • VolgaVolga, Только что выставил заголовок. Проблема осталась, а заголовки ответов такого вида:
    Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: http://localhost:5173 Connection: keep-alive Content-Length: 205 Content-Type: application/json; charset=utf-8 Date: Mon, 09 Oct 2023 14:08:52 GMT Etag: W/"cd-WkNxHEyDI1rwZH+foiVDjvojblI" Keep-Alive: timeout=5 Set-Cookie: token=...; Max-Age=3600; Path=/; Expires=Mon, 09 Oct 2023 15:08:52 GMT; HttpOnly Vary: Origin X-Powered-By: Express

    Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: http://localhost:5173 Connection: keep-alive Content-Length: 205 Content-Type: application/json; charset=utf-8 Date: Mon, 09 Oct 2023 14:08:52 GMT Etag: W/"cd-WkNxHEyDI1rwZH+foiVDjvojblI" Keep-Alive: timeout=5 Set-Cookie: token=...; Max-Age=3600; Path=/; Expires=Mon, 09 Oct 2023 15:08:52 GMT; HttpOnly Vary: Origin X-Powered-By: Express

  • Andy Koshman, SameSite для куки выставьте и Secure.
    Firefox пишет ошибки в консоль при невозможности записать куки. Попробуйте в нём.
  • Совсем забыл - для fetch запроса тоже надо выставить "credentials: 'include'".
  • VolgaVolga, Получилось, токен сохранился, спасибо большое)
  • Ответы:

    Браузер по умолчанию запрещает Javascript записывать куки для доменов используйте прокси

    • HttpOnly куки сетятся на сервере.
    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Игорь Волков Ответ

    Есть несколько возможных причин, по которым у вас может не получаться записать токен аутентификации в cookie. Давайте рассмотрим некоторые из них:

    1. Неправильная установка параметров cookie:
    Убедитесь, что вы правильно устанавливаете параметры cookie, такие как срок действия, путь и домен. Например, если вы пытаетесь установить cookie сроком на 1 день, но указываете неправильный формат срока действия, то cookie может не устанавливаться.

    2. Проблемы с безопасностью:
    Браузеры имеют различные политики безопасности, которые могут предотвращать установку некоторых cookie. Например, если ваш сайт не использует HTTPS, то браузеры могут блокировать установку cookie с помеченным атрибутом Secure.

    3. Проблемы с SameSite:
    Недавно был введен атрибут SameSite для cookie, который помогает защитить пользователей от некоторых видов атак. Убедитесь, что вы правильно устанавливаете этот атрибут в соответствии с вашими требованиями безопасности.

    4. Проблемы с путем cookie:
    Убедитесь, что вы правильно указываете путь для cookie. Если вы устанавливаете cookie на одной странице, а пытаетесь получить его на другой, то cookie может быть недоступен из-за неправильно указанного пути.

    Вот пример кода на PHP, который может помочь вам установить cookie с токеном аутентификации:

     

    Убедитесь, что вы правильно настроили параметры cookie и следуете рекомендациям безопасности. Если проблема сохраняется, проверьте консоль браузера на наличие ошибок и попробуйте провести отладку вашего кода.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно