Hi I am a beginner and building a MERN app, its been 3 days i am trying to get cookies, I am able to see the cookies in the google network section which shows set cookies: and my cookies But when I open the application section to see cookies its completely empty i tried changing brwsers but all in vain. Kindly help me in this regard, I have not slept properly due to this error, I'll really appreciate this. This is my Backend login code:
import User from "../models/user.model.js";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import createError from "../utils/createError.js";
export const register = async (req, res, next) => {
try {
const hash = bcrypt.hashSync(req.body.password, 5);
const newUser = new User({
...req.body,
password: hash,
});
await newUser.save();
res.status(201).send("User created successfuly!");
} catch (err) {
next(err);
}
};
export const login = async (req, res, next) => {
try {
const user = await User.findOne({ username: req.body.username });
if (!user) return next(createError(404, "User not found!"));
const isCorrect = bcrypt.compareSync(req.body.password, user.password);
if (!isCorrect) return next(createError(400, "Wrong password or username"));
const token = jwt.sign(
{
id: user._id,
isSeller: user.isSeller,
},
process.env.JWT_KEY,{expiresIn:"1h"}
);
const { password, ...info } = user._doc;
res
.cookie("accessToken", token, {
httpOnly: true,
sameSite: "none",
secure: true,
})
.status(200)
.send(info); //new line
} catch (err) {
next(err);
}
};
export const logout = async (req, res, next) => {
res
.clearCookie("accessToken", {
sameSite: "none",
secure: true,
})
.status(200)
.send("User has been logged out!");
};
This is my Front end Login code:
import React from "react";
import { useState } from "react";
import "./Login.scss";
import axios from "axios";
const Login = () => {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState(null);
const handleSubmit = async (e) => {
e.preventDefault();
try {
const res = await axios.post(
"http://localhost:8080/api/auth/login",
{
username,
password,
},
{ withCredentials: true }
);
console.log(res.data);
console.log(res.headers);
console.log(document.cookie);
} catch (err) {
setError(err);
console.log(err);
}
};
return (
<div className="login">
<form onSubmit={handleSubmit}>
<h1>Sign in</h1>
<label htmlFor="">Username</label>
<input
name="username"
type="text"
placeholder="johndoe"
onChange={(e) => setUsername(e.target.value)}
/>
<label htmlFor="">Password</label>
<input
name="password"
type="password"
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Login</button>
{error && error.message}
</form>
</div>
);
};
export default Login;
This is my server.js
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";
import userRoute from "./routes/user.route.js";
import authRoute from "./routes/auth.route.js";
import cookieParser from "cookie-parser";
import cors from "cors"
const app = express();
//Some endpoints to remove eror || MiddleWares
app.use(express.json());
app.use(cookieParser());
app.use(cors({
origin:"http://127.0.0.1:5173",
credentials:true,
exposedHeaders: ['set-cookie'],// new line added
}))
dotenv.config();
const connect = async () => {
try {
await mongoose.connect(process.env.MONGO);
console.log("Connected to mongoDB!");
} catch (error) {
console.log(error);
}
};
//Routes Use
app.use("/api/auth", authRoute);
app.use("/api/users", userRoute);
app.use((err, req, res, next) => {
const errorStatus = err.status || 500;
const errMessage = err.message || "Something went wrong"
return res.status(errorStatus).send(errMessage)
});
app.listen(8080, () => {
connect();
console.log("Backend server Js runing...");
});
Token name is accessToken which is showing in Network tab but not in he application cookie tab
It might happen because Chrome only allows localhost with httpOnly: true
set in cookies.
So in your origin, you need to change the origin from 127.0.0.1 to localhost as:
app.use(cors({
origin:"http://localhost:5173",
credentials:true,
exposedHeaders: ['set-cookie'],// new line added
}))
Also if you are using Vite instead of CRA (Create React App ): as Vite uses 127.0.0.1 instead of localhost, then you need to change the vite config file as ( so that Vite uses localhost )
import { defineConfig} from "vite";
import react from "@vitejs/plugin-react";
import dns from 'dns'
dns.setDefaultResultOrder('verbatim')
export default defineConfig({
plugins: [react()],
server: {
host: "localhost",
port: "5173",
},
});
I hope you have solved your problem 👍.