Файл cookie не устанавливается в браузере
Я пытаюсь прочитать файл cookie с помощью cookie-parser.
console.log('req.cookies =', req.cookies);
Возвращает пустой объект.
Делал по туториалу на пятом часу. Единственное отличие в том что ютубер делал на vite js а я на webpack (create-react-app).
Пользователь авторизован. Искал на всевозможных сайтах читал коментарии в ютюбе где у многих людей были такие же ошибки (на них кстати так и не ответили) перепробовал все withCredentials: true, credentials:include(этот метод вообще выдает еще одну ошибку которую я описал ниже), поменял настройки куки в браузере заходил в инкогнито может дополнительная информация там будет но ничего не нашел. Я не понял но кто то писал что нужно купить домен хотя почему у остальных это работает без него?
При тестировании на insomnia (тоже что и postman) работает нормально:
Но при взаимодействии с браузером выводит это:
Бэкэнд index.js
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";
import userRoutes from "./routes/user.route.js"
import authRoutes from "./routes/auth.route.js"
import cors from 'cors'
import cookieParser from "cookie-parser";
const PORT = 9753
dotenv.config()
mongoose
.connect(process.env.MONGO)
.then(() => {
console.log('MongoDb is connectedd');
}).catch(err => {
console.log(err);
})
const app = express();
app.use(express.json())
app.use(cookieParser())
app.use(cors());
app.listen(PORT, () => {
console.log(`Server is runninng on port ${PORT}`);
})
app.use('/api/user', userRoutes);
app.use('/api/auth', authRoutes);
app.use((err, req, res, next) => {
const statusCode = err.statusCode || 500;
const message = err.message || 'Inrernal server error';
res.status(statusCode).json({
success: false,
statusCode,
message
})
})
user.route.js
import express from 'express';
import { test, updateUser } from '../controllers/user.controller.js';
import { verifyToken } from '../utils/verifyUser.js';
const router = express.Router();
router.get('/test', test)
router.put('/update/:userId', verifyToken, updateUser)
export default router;
verifyUser.js
import jwt from 'jsonwebtoken';
import { errorHandler } from './error.js'
export const verifyToken = (req, res, next) => {
const token = req.cookies.access_token;
console.log('req.cookies =', req.cookies); // выдает --> req.cookies = [Object: null prototype] {}
if (!token) {
return next(errorHandler(401, 'Unauthorized, req.cookies = [Object: null prototype] {}'))
}
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
console.log(user, 'user');
if (err) {
return next(errorHandler(401, 'Unauthorized22'))
}
req.user = user;
next();
})
}
DashProfile.js
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import './DashProfile.scss'
import { useRef } from "react";
import {getDownloadURL, getStorage, ref, uploadBytesResumable} from 'firebase/storage'
import { app } from "../../firebase.js";
import { CircularProgressbar } from 'react-circular-progressbar';
import 'react-circular-progressbar/dist/styles.css';
import { updateStart, updateSuccess, updateFailure } from "../../redux/user/userSlice.js";
import { useDispatch } from "react-redux";
export const DashProfile = () => {
const {currentUser} = useSelector(state => state.user)
const [imageFile, setImageFile] = useState(false)
const [imageFileUrl, setImageFileUrl] = useState(false)
const [imageFileUploadProgress, setImageFileUploadProgress] = useState(false)
const [imageFileUploadError, setImageFileUploadError] = useState(false)
const [formData, setFormData] = useState({})
const filePickerRef = useRef()
const dispatch = useDispatch()
const hadleImageChange = (e) => {
const file = e.target.files[0]
if(file){
setImageFile(file)
setImageFileUrl(URL.createObjectURL(file))
}
}
useEffect(() => {
if(imageFile){
uploadImage()
}
},[imageFile])
const uploadImage = async () => {
setImageFileUploadError(false)
const storage = getStorage(app);
const fileName = new Date().getTime() + imageFile.name;
const storageRef = ref(storage, fileName)
const uploadTask = uploadBytesResumable(storageRef, imageFile)
uploadTask.on(
'state_changed',
(snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
setImageFileUploadProgress(progress.toFixed(0))
},
(error) => {
setImageFileUploadError('Не удалось загрузить изображение (файл должен быть меньше 2MB)')
setImageFileUploadProgress(false)
setImageFile(false)
setImageFileUrl(false)
},
() => {
getDownloadURL(uploadTask.snapshot.ref)
.then((downloadURL)=> {
setImageFileUrl(downloadURL);
setFormData({...formData, profilePicture: downloadURL});
})
}
)
}
const handleChange = (e) => {
setFormData({...formData, [e.target.id]: e.target.value})
}
const handleSubmit = async (e) => {
e.preventDefault()
if(Object.keys(formData).length === 0){
return;
}
try {
dispatch(updateStart());
const res = await fetch(`http://localhost:9753/api/user/update/${currentUser._id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
});
const data = await res.json();
console.log(data);
if(!res.ok){
dispatch(updateFailure(data.message));
}else{
dispatch(updateSuccess(data))
}
} catch (error) {
dispatch(updateFailure(error.message))
}
}
return (
<div className="dash-profile">
<h1 className="dash-profile__h1">Profile</h1>
<form onSubmit={handleSubmit} className="dash-profile__form">
<input type="file" accept="image/*" onChange={hadleImageChange} ref={filePickerRef} className="dash-profile__file-input"/>
<div className="dash-profile__image" onClick={() => filePickerRef.current.click()}>
<img src={imageFileUrl || currentUser.profilePicture} alt="user"/></div>
<div className="dash-profile__input-const">
<div className="dash-profile__input">
<input type="text" id="username" placeholder="username" defaultValue={currentUser.username} onChange={handleChange} />
</div>
</div>
<div className="dash-profile__input-const">
<div className="dash-profile__input">
<input type="email" id="email" placeholder="email" defaultValue={currentUser.email} onChange={handleChange} />
</div>
</div>
<div className="dash-profile__input-const">
<div className="dash-profile__input">
<input type="text" id="password" placeholder="password" onChange={handleChange} />
</div>
</div>
<button className="dash-profile__update">
<span>Обновить</span>
</button>
</form>
<div className="dash-profile__deleteandsignout">
<span>Удалить аккаунт</span>
<span>Выйти</span>
</div>
</div>
);
};
auth.controller.js Тут пользователь получает 'access_token' при входе. При тестировании access_token работает но при взаимодействии с сайтом нет
import User from "../models/user.model.js";
import bcryptjs from "bcryptjs";
import { errorHandler } from "../utils/error.js";
import jwt from 'jsonwebtoken';
export const signup = async (req, res, next) => {
const { username, email, password } = req.body;
if (!username || !email || !password || username === '' || email === '' || password === '') {
next(errorHandler(400, 'All fields are required'))
}
const hashedPassword = bcryptjs.hashSync(password, 10) //here was some not understandable problem
const newUser = new User({
username: username,
email: email,
password: hashedPassword,
});
try {
await newUser.save();
res.json('Signup successful');
} catch (error) {
next(error)
}
}
export const signin = async (req, res, next) => {
const { email, password } = req.body;
if (!email || !password || email === '' || password === '') {
next(errorHandler(400, 'All fields are required'))
}
try {
const validUser = await User.findOne({ email })
if (!validUser) {
return next(errorHandler(404, 'User not found'))
}
const validPassword = bcryptjs.compareSync(password, validUser.password)
if (!validPassword) {
return next(errorHandler(404, 'Invalid password'))
}
const token = jwt.sign(
{ id: validUser._id }, process.env.JWT_SECRET
);
const { password: pass, ...rest } = validUser._doc;
res
.status(200)
.cookie('access_token', token, {
httpOnly: true,
secure: false
})
.json(rest)
} catch (error) {
next(error)
}
}
export const google = async (req, res, next) => {
const { email, name, googlePhotoUrl } = req.body;
try {
const user = await User.findOne({ email })
if (user) {
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET);
const { password, ...rest } = user._doc;
res
.status(200)
.cookie('access_token', token, {
httpOnly: true,
secure: false
})
.json(rest);
} else {
const generatedPassword = Math.random().toString(36).slice(-8) + Math.random().toString(36).slice(-8)
const hashedPassword = bcryptjs.hashSync(generatedPassword, 10);
const newUser = new User({
username:
name.toLowerCase().split(' ').join('') +
Math.random().toString(9).slice(-4),
email: email,
password: hashedPassword,
profilePicture: googlePhotoUrl
});
await newUser.save();
const token = jwt.sign({ id: newUser._id }, process.env.JWT_SECRET);
const { password, ...rest } = newUser._doc;
res
.status(200)
.cookie('access_token', token, {
httpOnly: true,
secure: false
})
.json(rest);
}
} catch (error) {
next(error)
}
}
Здесь данные обновляются без проблем
Тут в хедере сет куки, в апликатион какой то другой куки пришел я совсем не знаю откуда он пришел произошло это когда я открыл ноут. Удивился конечно до этого ни одного куки не видел на моем хосте но не обрадовался так как название другое
Тут кстати готовый проект ютубера который делал этот проект можете тамм проверить
Это ошибка выдается когда я в свой fetch запрос добавил credentials:'include'
Позже: Решил ошибку добавив
app.use(cors({origin:'http://localhost:3000',credentials:true}))
в свой бэкенд
Но проблема остается та же
PUT http://localhost:9753/api/user/update/66268e1ba6ee32299f30423b 401 (Unauthorized)