Tayne
Tayne

Reputation: 101

Passport JS req.user is undefined

I've seen this question posted else where, however, none of those solutions appeared to work for me. Upon trying to console log the req.session and req.user, I have a return of the session as shown below, however, the req.user returns as undefined. I believe there is an issue when serializing the user as VS code alerts me that the "'id' property does not exist on type user" in the passport.serialUser function, but it console logs user.id properly (the object id of my user document).

If anyone is aware of what might be cause of the user.id property not existing/the user being undefined I would appreciate it.

passport.js file:

const LocalStrategy = require("passport-local").Strategy;
const bcrypt = require("bcrypt");
const User = require("../models/User");

const verifyCallback = (username, password, done) => {
  User.findOne({ username: username })
    .then((user) => {
      if (!user) {
        return done(null, false);
      }

      // Validate Password
      bcrypt.compare(password, user.password).then((isMatch) => {
        if (isMatch) {
          return done(null, user);
        } else {
          return done(null, false);
        }
      });
    })
    .catch((err) => {
      done(err);
    });
};

const strategy = new LocalStrategy(verifyCallback);

passport.use(strategy);

passport.serializeUser((user, done) => {
  done(null, user.id);
});

passport.deserializeUser((userId, done) => {
  User.findById(userId)
    .then((user) => {
      done(null, user);
    })
    .catch((err) => done(err));
});

index.js file:

  session({
    secret: process.env.SECRET,
    resave: false,
    saveUninitialized: true,
    store: sessionStore,
    cookie: {
      maxAge: 1000 * 60 * 60 * 24,
    },
  })
);

// Passport Auth Middleware
const passportConfig = require("./config/passport");

// Initialize Passport and Use Session for Serialize/Deserialization
app.use(passport.initialize());
app.use(passport.session());

app.use((req, res, next) => {
  console.log(req.session);
  console.log(req.user);
  next();
});

console log:

  cookie: {
    path: '/',
    _expires: 2021-11-17T02:08:23.650Z,
    originalMaxAge: 86400000,
    httpOnly: true
  }
}
undefined

User document example:

{"_id":{"$oid":"6186c13beb18d33d5088f7b2"},
"username":"coolguy9",
"password":"$2b$13$4p5apH8Q8k8hP4WpCNt6/O40M9I0jlkG.LXIE3d/V89Kmtmk1plxa",
"firstname":"Bob",
"lastname":"Woodhull",
"team":"Warehouse",
"createdAt":{"$date":{"$numberLong":"1636221243904"}},
"updatedAt":{"$date":{"$numberLong":"1636221243904"}},
"__v":{"$numberInt":"0"}}```

Upvotes: 0

Views: 811

Answers (2)

hoangdesu
hoangdesu

Reputation: 1

I've been struggling with this problem in the last couple of days and I wanna leave some comment here, which might be helpful.

I had this problem when switching from using Vite's proxy server to pure axios. I didn't need extra configs for cors since all the requests get proxied in the dev environment. But when switching to production build (which doesn't include the dev server), session cookies cannot be set in the browser. I'd like to add a bit more on top of Tayne's answer:

  1. On frontend: include credentials in all axios requests e.g. axios.defaults.withCredentials = true;
  2. On backend: origin cannot be wildcard *. You have to specify the endpoints of where the client connects from:
// server.js

app.use(
  cors({
    credentials: true,
    origin: [
      'http://localhost:5173',
      'http://localhost:3000',
      'https://your-domain.com',
    ],
  }),
);

Upvotes: 0

Tayne
Tayne

Reputation: 101

Solved the issue. In my loginAPI.js file on my front end, which contains the axios instance, I needed to include the option withCredentials: true.

Example:

  baseURL: "http://localhost:8000/api/",
  timeout: 1000,
  withCredentials: true,
});

Upvotes: 2

Related Questions