0

I am responding to request from client for protected resources based on whether the req.isAuthenticated() flag returns true or false

I am hosting my app on render

When i had completed the initial phases of the project on dev environment i decided to check if things were working fine , only to find it wasnt

Upon successfull login i am redirecting user to a home page and making an api call inside of useEffect to an endpoint called /getUserDetails , here i only send the resources if the req.isAuthenticated() returns true , this is happening in dev but not happening in production

I tried changing the order of middlewares , setting secure flag inside cookie inside express session to true

Relevant part of the code ---

import express from "express";
import dotenv from "dotenv";
import session from "express-session";
import cors from "cors";
import mongoose from "mongoose";
import passport from "passport";
import { Strategy as GoogleStrategy } from "passport-google-oauth20";
import MongoStore from "connect-mongo";
import { profileRouter } from "./routes/profileRouter.js";
//import "./utils/passport.js"
import { User } from "./models/User.js";
dotenv.config({ path: "./config.env" });
const app = express();

app.use(express.json());

//DATABASE CONNECTION
const DB = process.env.DB_STRING.replace("<password>", process.env.DB_PASSWORD);
mongoose
  .connect(DB)
  .then(() => {
    console.log("DATABASE CONNECTION WAS SUCCESSFULL!");
  })
  .catch((error) => {
    console.log(`${error} --- error connecting to DATABASE `);
  });

app.use(
  cors({
    origin:
      process.env.NODE_ENV === "development"
        ? process.env.CLIENT_URL_DEV
        : process.env.CLIENT_URL_PROD,
    credentials: true,
    methods: "GET,POST,PUT,DELETE",
  })
);

app.use(
  session({
    resave: false, //changes req,session.cookie when session object is modified
    saveUninitialized: false, //only stores session to session store if modified
    secret: process.env.SECRET,
    store: MongoStore.create({
      mongoUrl: DB,
      collectionName: "sessions",
    }),
    cookie: {
      maxAge: 1000 * 60 * 60,
      secure: process.env.NODE_ENV === "development" ? false : true
    },
  })
);

app.use(passport.initialize());
app.use(passport.session());

passport.use(
  new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: `${
        process.env.NODE_ENV === "development"
          ? process.env.API_URL_DEV + "/auth/google/callback"
          : process.env.API_URL_PROD + "/auth/google/callback"
      }`,
    },

    async (accessToken, refreshToken, profile, done) => {
      console.log(profile, " profile info \n");
      const userExists = await User.findOne({
        email: profile.emails[0].value,
        name: profile.displayName
      })

      if (!userExists) {

        await User.create({
          email: profile.emails[0].value,
          name: profile.displayName,
          profilePhoto: profile.photos[0].value
        });


      }

      return done(null, profile);
    }
  )
);

passport.serializeUser(function (user, done) {
  done(null, user);
});

passport.deserializeUser(function (user, done) {
  done(null, user);
});



app.get(
  "/auth/google/callback",
  passport.authenticate("google", {
    access_type: "offline",
    scope: ["email", "profile"],
  }),
  async (req, res) => {
    console.log(`/auth/google/callback hit with a req --- ${JSON.stringify(req.user)} \n`)
    if (!req.user) {
      res.status(400).json({ error: "Authentication failed" });
    } else {
     
      res.redirect(
        process.env.NODE_ENV === "development"
          ? process.env.CLIENT_URL_DEV 
          : process.env.CLIENT_URL_PROD
      );
    }
    // return user details
  }
);

app.use("/profile", profileRouter)

app.get("/", (req, res) => {
  console.log("get req received to / endpoint \n");
  res.send("<h1>Hello</h1>");
});

const PORT = process.env.PORT || 6007;

app.listen(PORT, () => {
  console.log(`server listening on port ${PORT} \n`);
});
2
  • can please elaborate exactly error is logging ? Have you checked env file of prod. ?
    – Jack
    Commented Jun 5 at 10:59
  • @Jack --- in the getUserDetails endpoint req.isAuthenticated() is false Commented Jun 5 at 11:23

1 Answer 1

0

It is likely because the connection you are using isn't encrypted, and the secure cookies can only be sent over HTTPS. Try setting secure to just to false to confirm.

Have a look at this post on setting up Nginx as a reverse proxy in docker (not 100% certain what you are using on the front end, but this looks like a Mongo-Express-React-Node app) to deal with HTTPS certificates:

https://stackoverflow.com/a/63226398/22857893

The guide from the above post:

https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71

Also, double-check your production environment variable and ensure there are no typos like http versus https.

2
  • based on whether the dev environment is production or development i am setting the secure flag to true in the case of latter and false in the case of former Commented Jun 6 at 5:19
  • Also i am using render to deploy Commented Jun 6 at 5:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.