Паспорт не сохраняет вложенный документ в req.user

passport.js

passport.serializeUser(function(user, done) {
  done(null, user._id);
});
passport.deserializeUser(function(id, done) {
  User
    .findById(id).exec()
    .then(function(user) {
      done(null, user);
    }, done)
  ;
});

passport.use(new LocalStrategy(function(username, password, done) {
  Local
    .findOne({ username: username })
    .select('username role hashedPassword')
    .exec()
    .then(function(local) {
      if (!local) {
        return done(null, false);
      }
      var validPassword = bcrypt.compareSync(password, local.hashedPassword);
      if (!validPassword) {
        return done(null, false);
      }
      else {
        User
          .findOne({ local: local })
          .populate('local')
          .exec()
          .then(function(user) {
            console.log('user: ', user); // has subdocument
            return done(null, user);
          })
        ;
      }
    })
  ;
}));

auth.routes.js

router.get('/current-user', Auth.isLoggedIn, function(req, res) {
  console.log('req.user: ', req.user); // doesn't have subdocument
  res.status(200).json(req.user);
});

выход

user:  { _id: 55d8c6f7e1092f25bb761690,
  local:
   { _id: 55d8c6f7e1092f25bb76168f,
     username: 'a',
     role: 'user',
     __v: 0 },
  __v: 0 }
    ✓ Can log in with valid credentials
req.user:  { _id: 55d8c6f7e1092f25bb761690,
  local: 55d8c6f7e1092f25bb76168f,
  __v: 0 }

Когда я сохраняю пользователя в req.userpassport.js), у него есть поддокумент local, Но когда я позже попытаюсь получить доступ req.user, это дает мне ObjectId вместо поддокумента.

Почему это? Как я могу получить поддокумент вместо ObjectId?

1 ответ

Решение

Примерно так работает паспорт:

  • стратегия вызывается, когда пользователь еще не вошел в систему; если логин был принят, то пользователь, которого вы передаете обратному вызову, передается serializeUser() храниться (частично) в хранилище сеансов. В вашем случае вы храните пользователя _id в сессионном магазине;
  • deserializeUser() вызывается, когда пользователь вошел в систему (другими словами, когда есть действительный сеанс). Значение сеанса (_id), и значение, которое передается обратному вызову, сохраняется как req.user,

Так что вам нужно заселить local от deserializeUser() тоже, иначе он не будет доступен в req.user,

Другие вопросы по тегам