Search code examples
node.jsexpresscookiescookie-httponly

How to parse signedCookies in express?


I send a cookie to my front-end thanks to express:

  // signing the token
  static generateToken(user: PartialUser): Cookie {
    return jwt.sign({ _id: user._id }, process.env.JWT_TOKEN_KEY, {
      expiresIn: "14d",
    });
    
  // sending the cookie
  return res
      .status(200)
      .cookie("myApp", token, {
        expires: new Date(Date.now() + msPerDay * 14),
        httpOnly: true,
        secure: true,
      })
      .json({ user });
    
  // initializing cookie parser in index.js:
  app.use(cookieParser(process.env.JWT_TOKEN_KEY));
  
  //parsing the cookie
  const authenticate = (req: Authenticate, res: Response, next: NextFunction) => {
  const { myApp } = req.signedCookies; 
  if (req.signedCookies) {
    return jwt.verify(
      myApp,
      process.env.JWT_TOKEN_KEY,
      (error, parsedToken) => {
        if (error) {
          return res.sendStatus(403);
        }

        req.cookie = { _id: parsedToken._id };
        return next();
      }
    );
  }
  return res.sendStatus(401);
};

The req.signedCookies object is always empty. So all my routes return a 403 - forbidden access. However, if I don't specify secure: true when sending the cookie, it works, because I can access it in req.cookies. The network tab shows that the cookie is correctly send along the client request.

How to fix this?

ps: I'm fine with using req.cookies, but my express server is hosted on Heroku and it never sends the cookie to the client, which is a custom https domain. This is why I'm trying the secure:true option. For now, it only works in localhost. Maybe the solution is elsewhere?


Solution

  • A cookie signature on one hand, and the secure option on the other hand, are actually two different things.

    The secure option restricts the cookie to be sent over https only. This is intended at avoiding eavesdropping over the network. Incoming cookies that are set as secure will by default always be exposed on req.cookies by cookie-parser.

    A cookie signature on the other hand is basically a cryptographic hash that is intended at making a cookie tamper-proof. It seems that with the cookie-parser package, you sign a cookie with the signed: true option. Only incoming cookies that have been explicitly signed will be exposed on req.signedCookies. Note this is all regardless of the secure option.