Search code examples
node.jsexpresscorsexpress-session

How can I set the domain attribute in express-session based on the request origin?


I'm using express session. I set the domain domain: 'mydomain.com' so that the session cookie can be set between subdomains- like api.mydomain.com and staging.mydomain.com.

But this prevents the Set-Cookie header from setting the cookie when testing with a localhost frontend. I get Set-Cookie was blocked because its Domain attribute was invalid with regards to the current host url.

So I need to make the domain attribute change to localhost if the origin is localhost.

If I conditionally set the domain, we don't have access to req:

  app.use(session({
      secret: 'very secret 12345', 
      resave: true,
      saveUninitialized: false,
      store: new MongoStore({ mongooseConnection: mongoose.connection }),
      cookie: {
        domain:
          req.get('origin').slice(0, 17) === 'http://localhost:' ? 'localhost' : 'mydomain.com',
        secure: true,
        httpOnly: true,
        sameSite:  none,
      },
    })
  );

This returns ReferenceError: req is not defined.

So I tried calling session in a custom middleware to get access to req:

  app.use((req, res, next) =>
        session({
      secret: 'very secret 12345',
      resave: true,
      saveUninitialized: false,
      store: new MongoStore({ mongooseConnection: mongoose.connection }),
      cookie: {
        domain:
          req.get('origin').slice(0, 17) === 'http://localhost:' ? 'localhost' : 'mydomain.com',
        secure: true,
        httpOnly: true,
        sameSite:  none,
      },
    })
  );

But it doesn't work. It seems that with this, res, req, and next don't get passed in to the middleware function that session() returns. I also trying calling the function session() that returned -session({..options..})() , but that didn't work either.

How can I set the domain attribute based on the request origin?


Solution

  • I had to call the function and pass in req, res, and next

      app.use((req, res, next) =>
        session({
          secret: 'very secret 12345', // to do, make environment variable for production
          resave: true,
          saveUninitialized: false,
          store: new MongoStore({ mongooseConnection: mongoose.connection }),
          cookie: {
            domain:
              req.get('origin').slice(0, 17) === 'http://localhost:' ? 'localhost' : 'mydomain.com',
            secure: true,
            httpOnly: true,
            sameSite:  none,
          },
          },
        })(req, res, next)
      );