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?
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.
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.
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.
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});
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With