2015-08-22 34 views
0

passport.js護照不救子文檔到req.user

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.user(在passport.js中),它具有子文檔local。但是當我稍後嘗試訪問req.user時,它會給我ObjectId而不是子文檔。

這是爲什麼?我如何獲得子文檔而不是ObjectId

+2

你是如何實現'deserializeUser()'的? – robertklep

+0

@robertklep我用代碼更新了我的問題。將'populate('local')'添加到'deserializeUser()'中修復它。謝謝!你能把它寫成答案嗎? –

回答

1

這大致護照是如何工作的:

  • 當用戶沒有在尚未登陸策略被稱爲;如果登錄被接受,那麼您傳遞給回調的用戶將被傳遞到serializeUser()以(部分)存儲在會話存儲中。在你的情況下,你將用戶_id存儲在會話存儲中;
  • deserializeUser()當用戶登錄時(換句話說,當有一個有效的會話時)被調用。會話值(_id)被傳遞給它,並且傳遞給回調的值被存儲爲req.user

所以,你需要填充從deserializeUser()local過,否則也不會在req.user可用。