Cookie not set in Browser on Production

Viewed 205

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.

0 Answers
Related