I am using express.js as a server and next.js on my client, on 2 different servers.
I have been able to configure the cookie to be added to the browser locally but not when deployed in production.
I am using passport & express-session to log a user in and create a session to add the cookie to the browser and save the session in a mongodb database.
Server
In my main server file that spins up the server I have the following.
process.env.CLIENT_URL locally returns http://localhost:3000 and in production returns the exact client URL as it is in production, I have logged it to ensure that it is correct.
const express = require('express');
const cookieParser = require('cookie-parser');
require('dotenv').config();
// app
const app = express();
// execute database connection
const db = require('./database');
// connect to database
db.connect();
// create session
require('./middlewares').init(app, db);
app.use(express.urlencoded({ extended: true, limit: '5mb' }));
app.use(express.json());
app.use(cookieParser());
const apolloServer = require('./graphql').createApolloServer();
apolloServer.applyMiddleware({
app,
cors: { credentials: true, origin: process.env.CLIENT_URL },
});
// port
const port = process.env.PORT || 8000;
const server = app.listen(port, () => {
console.log(` Server is running on port ${port}`);
});
Then for when a user logs in, and what should apply the cookies to the browser, I have the following.
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (error, user) => {
done(error, user);
});
});
passport.use('graphql', ...);
const sess = {
name: 'portfolio-session',
secret: process.env.SESSION_SECRET,
cookie: { maxAge: 2 * 60 * 60 * 1000 },
resave: false,
saveUninitialized: false,
store: db.initSessionStore(),
};
server.use(session(sess));
server.use(passport.initialize());
server.use(passport.session());
Client
For my ApolloProvider I have HOC to add the provider to each page, and here, setting the credentials to include and setting the uri of the server. process.env.BASE_URL locally returns http://localhost:8000 and in production, again I logged it and it is the correct URL, making requests to the server work fine and there are no CORS errors.
import withApollo from "next-with-apollo";
import ApolloClient, { InMemoryCache } from "apollo-boost";
import { ApolloProvider } from "@apollo/react-hooks";
export default withApollo(
({ initialState, headers }) => {
const uri = process.env.BASE_URL;
return new ApolloClient({
request: (operation) => {
operation.setContext({
fetchOptions: {
credentials: "include",
},
headers,
});
},
uri,
cache: new InMemoryCache().restore(initialState || {}),
});
},
{
render: ({ Page, props }) => {
return (
<ApolloProvider client={props.apollo}>
<Page {...props} />
</ApolloProvider>
);
},
}
);
As I mentioned, works totally fine locally, the cookie gets applied to the browser as expected. Just not in production, I assume I am missing some sort of configuration, but doing some research, I can't see what?
Any help would be greatly appreciated.