0

I am unable to set session cookies in the browser with my MERN stack app. When both the express server and the react front end are running locally the cookies are set no problem. The problem raises itself after I deployed the express backend to heroku. I tried setting the "sameSite" cookie option to "lax" or to false even but the problem persists.

here's the configuration I use for express session.

sessionConfig = {
secret: process.env.SESSION_SECRET,
resave: false,

saveUninitialized: true,
cookie: {
  secure: false,
  httpOnly: true,
  expires: expiryDate,
  sameSite: "lax",
},
store: MongoStore.create({
  mongoUrl: process.env.MONGO_CONNECTION_STRING,
}),
}

app.set("trust proxy", 1);
app.use(cors({ origin: true, credentials: true }));
app.use(session(sessionConfig));

EDIT: to further clarify. if I visit the root route of my express app from the browser the cookies are set normally even when the app is deployed.(IE: if I type the url of the deployed heroku app, the session cookie is set) if I make the call from the react front end that is running locally though( using fetch api) to the deployed backend, the cookie is not set. This leads me to think it could have something to do with the same site cookie option.

Lin Du
  • 88,126
  • 95
  • 281
  • 483
Karim Kamel
  • 75
  • 1
  • 8

2 Answers2

1

I realized what was causing the problem. It was a security feature in chrome that doesn't allow setting sameSite cookie option to none, unless the cookie is also set to secure. You can read more about it here issue with cross-site cookies: how to set cookie from backend to frontend or here https://medium.com/@arcagarwal/same-site-changes-in-chrome-1c86973454f9

Karim Kamel
  • 75
  • 1
  • 8
0

I had this same issue,

Have you looked into the domain & path option in the cookie config?

  • domain: a string indicating the domain of the cookie (no default).
  • path: a string indicating the path of the cookie (/ by default).

Refer to my answer: https://stackoverflow.com/a/67341751/12408623

Are you using CRA? Is your MERN app present in a Monorepo?

Fixes:

1.Bundle the react app together with the server.

const express = require('express');
const path = require('path');
const app = express();
const PORT = 9000;

// You'll need to path join to your react build directory
app.use(express.static(path.join(__dirname, 'build')));

app.get('/', function (req, res) {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

app.listen(PORT);

2.Use JWTs to maintain token-based sessions.

I would say this approach would be more robust. However, JWTs are not ideal in every situation but should suffice in most.

If you have a monorepo MERN codebase where you decide to use JWTs. Then you can deploy both your client and server in different domains/platforms.

Check out this blog post I wrote about deploying a subdirectory to Heroku

https://shrynk.jagankaartik.live/tSepqC1qKF

Jagan Kaartik
  • 580
  • 2
  • 7
  • 15