2013-11-25 158 views
4

我正在開發一個將要部署到Heroku的Web應用程序。Express.js/Passport.js:req.user存儲在哪裏?

我選擇使用Node.js堆棧,因爲我厭倦了「傳統」web框架。我正在設計Express.js上的應用程序。我發現它比較高效和直觀。 Django或Grails。

因此,網絡應用程序將具有訪客和經過身份驗證的用戶的功能。隨着應用程序部署到Heroku,這是一個雲平臺服務,應用程序不能在服務器內部存儲任何內部狀態,因爲Heroku的負載均衡器和慣例是一般的。事實上,擁有內部狀態在分佈式環境中也是不好的設計。

我的本地開發設置有一個Redis實例(用於存儲會話)和一個MongoDB實例(用於存儲用戶數據,例如Facebook用戶詳細信息)。我使用Passport.js和護照-Facebook來處理認證。目前,我只實現了Facebook身份驗證,至少在本地運行良好。

問題是我不確定也沒有看到有關Express/Passport如何奇蹟般地填充對象的任何地方。我對此有點懷疑,感覺它存儲在服務器的內存中。

passport.serializeUser(function(user, done) { 
    console.log(
     "This outputs a complete" + 
     "User Profile object when the user logs in.", 
     user); 
    done(null, user); 
}); 

passport.deserializeUser(function(obj, done) { 
    console.log(
     "And this too, but I'm afraid that" + 
     "obj comes from memory.", 
     obj); 
    done(null, obj); 
}); 

Passport.js documentation對此不太清楚。我的猜測是serializeUser()從Facebook獲取用戶,但是deserializeUser()從內存中獲取它?

如果是這樣,是否將解決方案將原始用戶數據轉儲到serializeUser()中的Mongo數據庫中,然後從deserializeUser()中獲取它?

回答

5

req.user是一個便利屬性,它是req.session.user的別名,存儲在redis中。因此,對於啓用會話的請求,會話數據是從redis中加載的,然後req.user被設置爲與req.session.user相同,然後您的代碼將運行並響應請求,並且這些內存中的版本符合垃圾一旦收到回覆就收集。直到會話過期,redis中的副本才能存活。

如果是這樣,是否將解決方案將原始用戶數據轉儲到serializeUser()中的Mongo數據庫中,然後從deserializeUser()中獲取它?

是的,如果您想將用戶數據用作應用程序數據的一部分(這是典型的),那麼這就是一般模式。所以最後mongo會讓每一個曾經登錄過的用戶都知道,而且redis會讓每個用戶都擁有一個當前活動的會話,並且內存將讓每個用戶都處於這個瞬間處理請求的過程中。

+0

作爲Redis的noobie,我已經查詢密鑰,在Redis的CLI,但並沒有礙着GET命令實際訪問的重點內容。現在我看到Redis存儲的是與deserializeUser()相同的JSON。感謝您的回覆。 – tukkajukka

+0

我知道這個評論是在3年前發佈的,但作爲一個類似的Redis noob,我只是犯了完全相同的錯誤,這對我非常有幫助,謝謝。 – BML91