Search code examples
javascriptnode.jsexpresscookiesjwt

Passing cookies through routes Nodejs express


I have an server and i use jws to generate a token and the store it in a cookie, but when i try to authenticate the router cant find the cookie it just returns undefined

Express router

const { adminAuth } = require("../middleware/auth");
router.route("/deleteUser").delete(adminAuth, deleteUser);

middleware/auth

exports.adminAuth = (req, res, next) => {
  console.log(req.cookies);
  const token = req.cookies.jwt;
  if (token) {
    jwToken.verify(token, jwtSecret, (err, decodedToken) => {
      if (err) {
        return res.status(401).json({ message: "Not authorized" });
      } else {
        if (decodedToken.role !== "admin") {
          return res.status(401).json({ message: "Not authorized" });
        } else {
          next();
        }
      }
    });
  } else {
    return res
      .status(401)
      .json({ message: "Not authorized, token not available" });
  }
};

I have checked that the adminAuth works it just dont work when i access it through the router. i where expecting that it would just pass through the router but aprently the cookies does not


Solution

  • I think you are facing the issue because the cookies are not being parsed properly in your application.

    1. Firstly, install cookie-parser:
    • npm i --save cookie-parser or yarn add cookie-parser
    1. After that make sure to set it up to your server:

    const express = require("express");
    const cookieParser = require("cookie-parser");
    const app = express();
    
    app.use(cookieParser()); // use this

    1. Make sure that the cookie is being set properly.

    //Send the cookie to the client from whatever route you have (eg: login route)
    res.cookie("jwt", token, {
      httpOnly: true, // it is to prevent client-side scripts from accessing the cookie
      secure: process.env.NODE_ENV === "production", // only send over HTTPS in production (process.env is environmental variable. You can access it by npm i -s dotenv or yarn add dotenv and require it at the top of your server/backend and create a .env file and write NODE_ENV=developement or production inside of it)
      sameSite: "strict", // prevent CSRF
      maxAge: 24 * 60 * 60 * 1000 // cookie expires after 1 day. It is in milliseconds
    });
    
    //And to remove the cookie, if you have a logout route
    res.clearCookie("jwt");

    1. Check the client request again:

    /******************************************************************
    **                  If you are using fetch                       **
    ******************************************************************/
    
    fetch('/deleteUser', {
      method: 'DELETE',
      credentials: 'include', // do this to make sure that you are sending cookies
    });
    
    /******************************************************************
    **                  If you are using axios                       **
    ******************************************************************/
    
    axios.delete('/deleteUser', {
      withCredentials: true, // do this to make sure that you are sending cookies
    });

    1. Check cors config (If you are working with cross origin requests).

    const cors = require("cors");
    
    app.use(cors({
      origin: 'http://your-client-url', // allow only your client app url
      credentials: true // enable credentials (cookies) to be sent
    }));

    1. If the app still doesn't work (If you followed my instructions properly, it should), I would restart the pc and run the code again. And if the problem is still there, I would rewrite the code in a new file and try from start.