I created a front-end application using React and then deployed it on Netlify. The frontend application interacts with an express backend application that I created and deployed to Render. Any interaction between frontend and backend is protected by authentication using passportjs. The backend application uses passport's local policy to verify that the user exists/that the username and password are correct by connecting to mongoDB. Once confirmed, I use passport's serialization and deserialization functions to maintain the login session.
During development, I use this application on http://localhost. In the meantime, everything works as expected. The login session is saved as a cookie, which I am able to send to the backend application as part of future requests to authenticate the user.
When I deploy the frontend app to Netlify and the backend app to Render, the session cookie is no longer saved which means the user cannot authenticate on the backend as every request after login The saved session cookie is sent to the backend.
In a little more detail, for express-session with passport to create a login session, I use connect-mongo to store the session on MongoDB. Every time I log in via the frontend I can see the session being created and stored in MongoDB. The problem seems to be that the cookies in the response are not being passed over and I don't know why.
This is the session options I currently have in my express backend application:
app.use( session({ secret: process.env.SESSION_SECRET, save: false, saveUninitialized: false, store: MongoStore.create({ mongoUrl: process.env.MONGODB_URI }), cookie: { secure: true, sameSite: "none", httpOnly: true, expires: 24 * 60*60*1000 } }) );
I have tried searching for a solution and tried many options including changing secure
, changing httpOnly
, changing sameSite
Set to false and none, add domain
pointing to the frontend URL and another domain
pointing to the backend URL, remove any security packages I have installed like helmet and rate limiter, but it doesn't seem to have any effect.
I also set the credential's Access Control header to true:
app.use((req, res, next) => { res.setHeader("Access-Control-Allow-Origin", process.env.DOMAIN_URL); res.setHeader("Access-Control-Allow-Credentials", true); res.setHeader("Access-Control-Allow-Headers", "Content-Type"); res.header("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE"); next(); });
For all requests, I use fetch
. I ran into a question similar to mine, but it wasn't answered: Browser not saving session cookie from cross domain server
Any help or advice is greatly appreciated!
problem solved. The problem is with trusting the proxy. Since I'm running multiple nameservers, the backend is behind a reverse proxy. By enabling trusting the proxy, my backend application will understand that it is behind a proxy and can trust the X-Forwarded-header field. To enable it, I added the following code in my backend application: