Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cookie not set with express-session in production

My app is divided between Client and Server. Client is a frontend side Nextjs app hosted on Now.sh, Server is its backend created with Express and hosted on Heroku, so the domains are client-app.now.sh and server-app.herokuapp.com .


Authentication

Authentication system is based on cookies and I'm using express-session to achieve it. This is my express-session configuration

app.use(
  session({
    store:
      process.env.NODE_ENV === "production"
        ? new RedisStore({
            url: process.env.REDIS_URL
          })
        : new RedisStore({
            host: "localhost",
            port: 6379,
            client
          }),
    name: "sessionID",
    resave: false,
    saveUninitialized: false,
    secret: keys.SESSION,
    unset: "destroy",
    cookie: {
      domain:
        process.env.NODE_ENV === "production"
          ? ".client-app.now.sh"
          : "localhost",
      secure: process.env.NODE_ENV === "production",
      httpOnly: true,
      maxAge: 7 * 24 * 60 * 60 * 1000
    }
  })
);

Cors is set with the "cors" package:

app.use(
  cors({
    origin:
      process.env.NODE_ENV === "production"
        ? process.env.CLIENT_URL
        : "http://localhost:3000",
    credentials: true
  })
);

Client is configured with Apollo and "credentials" in HttpLink is set to "include".

The problem is that cookie with session ID is correctly set in development, but not in production. Could this be related to the fact that I'm hosting client and server on different domains?

like image 773
The_Wolf Avatar asked Dec 17 '18 16:12

The_Wolf


People also ask

Can express-session be used in production?

With a negative final score, it's clear that express-session is not optimal for production apps – especially ones that care about user security and will likely scale with time.

Does Express-session use cookies?

Here is a simple explanation: - A user session can be stored in two main ways with cookies: on the server or on the client. express-session stores only a session identifier on the client within a cookie and stores the session data on the server, typically in a database.

How does express cookie session work?

Express. js uses a cookie to store a session id (with an encryption signature) in the user's browser and then, on subsequent requests, uses the value of that cookie to retrieve session information stored on the server.

How can express set a cookie on the client?

In order to correctly set cookies accessible on the client just use a snippet like the following: res. cookie('rememberme', 'yes', { maxAge: 900000, httpOnly: false});


1 Answers

I had my production node server behind a reverse proxy. This causes node to not trust the proxy and thus not set cookies.

I had to enable trusting the first proxy when in production.

app.set('trust proxy', 1) // trust first proxy

More info check out express-session's docs on the topic.

like image 88
Sir.Nathan Stassen Avatar answered Sep 21 '22 13:09

Sir.Nathan Stassen