Search code examples
reactjsexpresscookiesjwt

Express and React Token Authentication: req.cookies is empty in application but works in Postman


I'm building a web application using React for the frontend and Express for the backend. I'm trying to implement token-based authentication using cookies. The setup works perfectly in Postman, but when I try to run it from my React application, req.cookies is always an empty object.

In my Express application, I set the token in an HTTP-only cookie like this:

const token = await user.generateToken();
res.status(200)
    .cookie("access_token", token, {
        httpOnly: true,
        secure: false,
        sameSite: "none",
    }).json({ message: "Token set", data });


I have a middleware function to verify the token:

export const verifyToken = (req, res, next) => {
    const token = req.cookies.access_token;
    console.log(req.cookies); // This logs an empty object in the browser, but works fine in Postman
    if (!token) return res.status(401).json({ message: "Access denied" });

    jwt.verify(token, process.env.SECRET, (err, user) => {
        if (err) return res.status(403).json({ message: "Invalid token" });
        req.user = user;
        next();
    });
};


In my React application, I'm making the request like this:

const apiCall = await axios.post(
    "http://localhost:3000/event/create",
    data,
    {
         withCredentials: true,
         credentials: "include",
         headers: {
             "Access-Control-Allow-Credentials": true, // This header is not necessary and can be removed
         },
    }
);


Thi is my middle were i am using

const express = require('express');
const cors = require('cors');
const cookieParser = require('cookie-parser');
const jwt = require('jsonwebtoken');
const app = express();

app.use(cookieParser());
app.use(express.json());
app.use(cors({
    origin: "http://localhost:5173",
    credentials: true,
}));


Solution

  • The sameSite:'none' requires Secure as well. Please remove it.

    Code revised

    res.status(200)
        .cookie("access_token", token, {
            httpOnly: true,
            secure: false,
        }).json({ message: "Token set", data });
    

    When sameSite:'none' and Secure is missing, then the error below will be logged in Browser.

    Error logged in Chrome Browser/Application/Storage/Cookies

    Mark cross-site cookies as Secure to allow setting them in cross-site contexts

    Cookies marked with SameSite=None must also be marked with Secure to allow setting them in a cross-site context. This behavior protects user data from being sent over an insecure connection. Resolve this issue by updating the attributes of the cookie:...

    Citation:

    Set-Cookie