Search code examples
node.jsexpresssessionredispassport.js

req.user is undefined when accessing other routes after passport authentication


I'm using the custom error handling of passportjs. When I finished authenticating and now redirect to other route, the req.user is now undefined on that route. Are there any configurations I need to do?

(req: any, res, next) => {
    passport.authenticate('local-register', (err, user, info) => {
      if (err) {
        return next('Error Auth');
      }
      if (info) {
        return next('Error Auth');
      }
      if (!user) {
        return next('Error Auth'); 
      }
      req.logIn(user, (error: Error) => {
        if (error) {
          return next('Error Auth');
        }
        return next();
      });

    })(req, res, next);
app.get('/home', async (req, res, next) => {
  console.log(req.user.id) // logs undefined
})

session.js file includes

const sessions = session({
  cookie: {
    maxAge: 86400000,
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production' ? true : 'auto',
    sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
  },
  name: 'sessionID',
  genid: () => {
    return nanoid(36);  
  },
  resave: false, 
  secret: process.env.SESSION_SECRET ?? '',  
  saveUninitialized: false, 
  store: new Reddistore({ client: redisClient }),
});

my index.js file includes

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

Solution

  • in your index.js file

    const passport = require('passport');
    const { passportStrategy } = require('./config/passportStrategy');
    passportStrategy(passport);
    

    in config/passportStrategy.js file

    const {
      Strategy, ExtractJwt 
    } = require('passport-jwt');
    const User = require('../model/user');
    
    const passportStrategy = (passport) => {
      const options = {};
      options.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
      options.secretOrKey = "YOUR_SECRET";
      passport.use('local-register',
        new Strategy(options, async (payload, done) => {
          try {
            const result = await User.findOne({ _id: payload.id });
            if (result) {
              return done(null, result.toJSON());
            }
            return done('No User Found', {});
          } catch (error) {
            return done(error,{});
          }
        })
      );   
    };
    
    module.exports = { passportStrategy };
    

    // your middleware should like this

    (req: any, res, next) => {
        passport.authenticate('local-register', (err, user, info) => {
          if (err) {
            return next('Error Auth');
          }
          if (info) {
            return next('Error Auth');
          }
          if (!user) {
            return next('Error Auth'); 
          }
          req.user = user; // <=== assign user to req.user
          req.logIn(user, (error: Error) => {
            if (error) {
              return next('Error Auth');
            }
            return next();
          });
    
        })(req, res, next);
    
    
    app.get('/home', async (req, res, next) => {
      console.log(req.user.id) // now you can access user
    })