Home > database >  JS promise. Some node js and passport js. How can I get an internal structure from promise { {} }? r
JS promise. Some node js and passport js. How can I get an internal structure from promise { {} }? r

Time:10-07

I can't get an item from req.user, when I try to see what's in req.user, it displays:

Promise {
  {
    login: 'login',
    password: '$2b$10$sivL/8KvPYzlN/b24nWNOOa7pd02WX',
    id: 12,
    role: 'user'
  }
}

It turns out that I can output Promise { {} }, but I only need the internal structure, how can I get it for further processing (take for example only the role)?

req.user is sets there (According to the guide)

const LocalStrategy = require('passport-local').Strategy
const bcrypt = require('bcrypt')

function initialize(passport, getUserByEmail, getUserById) {
  const authenticateUser = async (email, password, done) => {
    const user = await getUserByEmail(email)
    if (user == null) {
      return done(null, false, { message: 'No user with that email' })
    }

    try {
      if (await bcrypt.compare(password, user.password)) {
        return done(null, user)
      } else {
        return done(null, false, { message: 'Password incorrect' })
      }
    } catch (e) {
      return done(e)
    }
  }

  passport.use(new LocalStrategy({ usernameField: 'email' }, authenticateUser))
  passport.serializeUser((user, done) => done(null, user.id))
  passport.deserializeUser((id, done) => {
    return done(null, getUserById(id))
  })
}

module.exports = initialize

CodePudding user response:

EDIT: After seeing your strategy, I can see the issue is in deserializeUser. It looks like getUserById returns a promise, so you need to get the result first:

  passport.deserializeUser(async (id, done) => {
    const user = await getUserById(id);
    return done(null, user);
  })

Previous answer in case it helps someone else:

Your issue is most likely in your login strategy and not where you want to consume req.user.

Assuming you're using the LocalStrategy for passport, you return the final resolved user record in the callback like so:

passport.use(new LocalStrategy(
  function(username, password, done) {
    // Example service returning a promise
    UserService.loginWithPassword({ username, password }.then((user) => {
      if (!user) return done(null, false);
      return done(null, user);
    }).catch(error => {
      return done(err);
    });
  }
));

If you don't resolve the promise with await or then, you will end up with a promise for req.user like you have in your question:

passport.use(new LocalStrategy(
  function(username, password, done) {
    // Example service returning a promise
    const user = UserService.loginWithPassword({ username, password });
    // user will always be a promise here
    if (!user) return done(null, false);
    return done(null, user);
    // now `req.user` is the promise, instead of the user object
  }
));

  • Related