Search code examples
expresscookiesjwtmernproduction

Safety of setting browser cookies from Express


Recently deployed a site of mine, and I am wondering if this solution to allowing the Express server on Heroku to set browser cookies for my Netlify React app is safe. I found it on an ill-explained SO answer elsewhere.

                                User.create(req.body)
                                .then(userNew => {
                                    res
                                        .cookie(
                                            "usertoken",
                                            jwt.sign({ _id: userNew._id }, process.env.JWT_KEY),
                                            {
                                                secure: true,
                                                sameSite: "none",
                                                httpOnly: false,
                                            }
                                        )
                                        .json({
                                            msg: "User registration success!",
                                            user: {
                                                _id: userNew._id,
                                                userName: userNew.userName,
                                                email: userNew.email,
                                                favs: userNew.favs,
                                            }
                                        });
                                })
                                .catch(err => res.status(400).json(err));

The httpOnly, secure, and sameSite options are my concern. I used to only have httpOnly set to 'true' in development with no issue, but this solution worked for me in production. Thanks!


Solution

    • Set httpOnly to true to prevent client-side access to the cookie
    • Make sure to set expiry for JWT with expiresIn option.
    • Set maxAge in cookie option same at that of JWT expiry.
    • You can track if you are in production or not with NODE_ENV environmental variable. You can set up your code in a way that you don't keep changing it during production and development.

    Here is how I commonly use the cookie along with JWT

      const isProd = process.env.NODE_ENV === 'production';
    
      res.cookie(
        'usertoken',
        jwt.sign({ _id: userNew._id }, process.env.JWT_KEY, { expiresIn: '1d' }),
        {
          secure: isProd,
          sameSite: isProd ? 'none' : 'lax',
          httpOnly: true,
          maxAge: 24 * 60 * 60 * 1000,
        }
      );