Search code examples
node.jsmongodbexpressmongoosepassport.js

Passport seem to not set properly req.user after initialization


I use Mongoose (connected to a mongoDB atlas cluster), ExpressJS, and NodeJS to make a login/authentication system but after login and initialize with Passport, req.user doesn't return the user info which is stored in the database but return this instead.

I use a console.log(req.user) to see what's going on and it print out this instead of the user info

Query {
  _mongooseOptions: {},
  _transforms: [],
  _hooks: Kareem { _pres: Map(0) {}, _posts: Map(0) {} },
  _executionCount: 0,
  mongooseCollection: NativeCollection {
    collection: Collection { s: [Object] },
    Promise: [Function: Promise],
    modelName: 'User',
    _closed: false,
    opts: {
      autoIndex: true,
      autoCreate: undefined,
      schemaUserProvidedOptions: {},
      capped: false,
      Promise: [Function: Promise],
      '$wasForceClosed': undefined
    },
    name: 'users',
    collectionName: 'users',
    conn: NativeConnection {
      base: [Mongoose],
      collections: [Object],
      models: [Object],
      config: {},
      replica: false,
      options: null,
      otherDbs: [],
      relatedDbs: {},
      states: [Object: null prototype],
      _readyState: 1,
      _closeCalled: undefined,
      _hasOpened: true,
      plugins: [],
      id: 0,
      _queue: [],
      _listening: false,
      _connectionString: 'mongodb+srv://davikzetus:[email protected]/test?retryWrites=true&w=majority',     
      _connectionOptions: [Object],
      client: [MongoClient],
      '$initialConnection': [Promise],
      _events: [Object: null prototype],
      _eventsCount: 1,
      name: 'test',
      host: 'ac-krjjmvv-shard-00-00.8kipjjz.mongodb.net',
      port: 27017,
      user: 'davikzetus',
      pass: '***********',
      db: [Db]
    },
    queue: [],
    buffer: false,
    emitter: EventEmitter {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: undefined,
      [Symbol(kCapture)]: false
    }
  },
  model: Model { User },
  schema: Schema {
    obj: {
      username: [Object],
      email: [Object],
      password: [Object],
      role: [Object]
    },
    paths: {
      username: [SchemaString],
      email: [SchemaString],
      password: [SchemaString],
      role: [SchemaString],
      _id: [ObjectId],
      __v: [SchemaNumber]
    },
    aliases: {},
    subpaths: {},
    virtuals: { id: [VirtualType] },
    singleNestedPaths: {},
    nested: {},
    inherits: {},
    callQueue: [],
    _indexes: [],
    methods: {},
    methodOptions: {},
    statics: {},
    tree: {
      username: [Object],
      email: [Object],
      password: [Object],
      role: [Object],
      _id: [Object],
      __v: [Function: Number],
      id: [VirtualType]
    },
    query: {},
    childSchemas: [],
    plugins: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
    '$id': 1,
    mapPaths: [],
    s: { hooks: [Kareem] },
    _userProvidedOptions: {},
    options: {
      typePojoToMixed: true,
      typeKey: 'type',
      id: true,
      noVirtualId: false,
      _id: true,
      noId: false,
      validateBeforeSave: true,
      read: null,
      shardKey: null,
      autoIndex: null,
      minimize: true,
      discriminatorKey: '__t',
      optimisticConcurrency: false,
      versionKey: '__v',
      capped: false,
      bufferCommands: true,
      strictQuery: false,
      strict: true,
      pluralization: true
    },
    '$globalPluginsApplied': true,
    _requiredpaths: [ 'role', 'password', 'email', 'username' ]
  },
  op: 'find',
  options: {},
  _conditions: { id: '64256e27f9e4e46834d7106b' },
  _fields: undefined,
  _update: undefined,
  _path: undefined,
  _distinct: undefined,
  _collection: NodeCollection {
    collection: NativeCollection {
      collection: [Collection],
      Promise: [Function: Promise],
      modelName: 'User',
      _closed: false,
      opts: [Object],
      name: 'users',
      collectionName: 'users',
      conn: [NativeConnection],
      queue: [],
      buffer: false,
      emitter: [EventEmitter]
    },
    collectionName: 'users'
  },
  _traceFunction: undefined,
  '$useProjection': true
}

passport-config.js

const LocalStrategy = require('passport-local').Strategy
const bcrypt = require('bcrypt')
const User = require('/Work Archive/LapTrinhWeb/FINALVFINAL/models/user')

async function initialize(passport, getUserByEmail, getUserById){
    const athenticateUser = async (email, password, done) => {
        const user = await getUserByEmail(email)
        if (user.length == 0){
            console.log(user._id)
            return done(null, false, {message : 'no user with that email'})
        }
        
        
        try{
            if( await bcrypt.compare(password, user[0].password)){
                return done(null, user)
            }
            else{
                return done(null,false,{message: 'password incorrect'})
            }
        }
        catch (err) {
            return done(err)
        }
        
    }
    passport.use(new LocalStrategy({ usernameField: 'email'}, athenticateUser))
    passport.serializeUser((user , done) => done(null, user[0].id))
    passport.deserializeUser((id,done) => {
        done(null, getUserById(id))
    })
 
}

module.exports = initialize

server.js

const express = require('express')
const app = express()
const expressLayouts = require('express-ejs-layouts')
const bodyParser = require('body-parser')
const methodOverride = require('method-override')
const bcrypt = require('bcrypt')
const passport = require('passport')
const flash = require('express-flash')
const session = require('express-session')
const {checkAuthenticated, checkNotAuthenticated} = require('./authenticates.js')


const initializePassport = require('./passport-config')

initializePassport(passport, 
                    email => User.find({email : email}),
                    id => User.find({id:id})
)

app.use(session({
  secret : process.env.SESSION_SECRET,
  resave : false,
  saveUninitialized : false
}))
app.use(passport.initialize())
app.use(passport.session())

app.get('/', checkAuthenticated, (req, res) => {
  res.render('login')
})

app.get('/login', checkNotAuthenticated, (req, res) => {
  res.render('login')
})

app.post('/login', checkNotAuthenticated, passport.authenticate('local', {
  successRedirect: '/',
  failureRedirect: '/login',
  failureFlash: true
}), (req,res) => {
  console.log(req.user)
})

app.get('/register', checkNotAuthenticated, (req, res) => {
  res.render('register.ejs')
})

app.post('/register', checkNotAuthenticated, async (req, res) => {
  try {
    const hashedPassword = await bcrypt.hash(req.body.password, 10)
    const users =  new User({
      username: req.body.username,
      email: req.body.email,
      password: hashedPassword,
      role : 'basic'
    })
    const newUser = await users.save()
    res.redirect('/login')
  } catch {
    res.redirect('/register')
  }
})
app.listen(process.env.PORT || 3000)

I try to check if session is actually being created by console.log(req.sessionID) and it did return Session ID, so i try req.session.user but it still return the same in console.log as req.user.

req.user was suppose to return something like this

[
  {
    _id: 64256e27f9e4e46834d7106b,
    username: 'w',
    email: 'w@w',
    password: '$2b$10$36eN7DN9d5H0r6DcSgL68OdL.ejNLPzD5qn0S.WTyoSbYCniNlKsS',
    role: 'basic',
    __v: 0
  }
]

Solution

  • i figure out the problem, its a syntax problem, another user also encounter this problem here : Auth using passport.js confusion with syntax?.