簡體   English   中英

如何正確使用Passport.js?

[英]How to properly use Passport.js?

我在用 :

  • Node.js的
  • 快遞4.0
  • Passport.js
  • Google OAuth 2用於身份驗證

對於每個用戶,我存儲在MySQL數據庫中(我沒有關於此技術的選擇)來自他的Google個人資料(電子郵件等...)的一些信息,訪問和刷新令牌,以及用戶提供的附加信息。他在我的應用程序上注冊。

我已經看到了passport.js的不同用途,特別是關於如何在會話中存儲該信息。

  1. passport.js的配置頁面上 ,我真的不明白以下代碼塊的要點:

     passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); }); 

    基本上,每次用戶發出請求或訪問頁面時,都會向DB請求並檢索信息。 有什么意義? 它減慢了應用程序的速度。 在調用serializeUser時(即,當信息存儲在會話中時),不應該檢索來自DB的信息嗎?

  2. 我已經讀過在session中存儲太多信息session降低應用程序的速度。 什么是“太多”? 應用程序會減慢多少錢? 有人知道某處是否有測試? 我的應用程序頁面需要一組關於我的用戶的不同數據(例如,主頁只需要他的名字,而個人資料頁面將需要所有內容,另一個頁面需要知道他擁有的汽車等...)。 passport.authenticate檢查用戶是否存在於數據庫中時,我是否應該將所有信息存儲在session中(從而將對數據庫的讀取請求限制為大約一個),或者僅在會話中存儲他的ID並讓我的頁面向該用戶發出附加請求。 DB有必要嗎?

  3. 我的另一個問題是:在注冊過程中,我首先讓用戶登錄他的Google帳戶,我將他的個人資料的詳細信息存儲在某個地方 ,讓他填寫表格以獲取其他信息,然后我將所有內容都插入到數據庫中。 問題是我不知道如何正確存儲他的Google帳戶詳細信息,直到它們插入數據庫。 目前,我將它們存儲在session ,然后在插入成功時刪除它。 更具體地說,當我的數據庫中沒有找到現有用戶時,我會在我的passport.authenticate回調中找到:

     return done(null,false,userInfo); 

    因此,用戶未經過身份驗證,我有兩個問題:我必須將userInfo存儲在某處,直到用戶注冊為止,我必須在注冊完成后使用req.login() “手動”登錄。

    我是否應該在登錄Google帳戶后立即對其進行身份驗證? 如果他沒有完成注冊,這不會給我帶來安全問題嗎?

  4. 最后,我讀過有關使用Reddis的內容。 這會幫助我解決這些問題嗎?

非常感謝你 !

1)serializeUser過濾數據並將其存儲在會話cookie中。 如果可以,通常在cookie中存儲較少。 無論如何,您將調用數據庫以獲取有關用戶的數據,因此您只需存儲用於檢索和重新構建用戶的ID,如deserializeUser中所示。

來自cookie的請求由客戶端提供給服務器,服務器將cookie反序列化為數據,解密cookie內容或從數據庫檢索用戶數據。 然后響應出來,服務器序列化客戶端數據,刮掉你不會存儲在cookie中的東西並將它們放入數據庫中,只需在cookie中留下一個id。

如果你正在進行加密,那么當你想通過運行多台機器進行擴展時,這很容易被搞砸,每台機器都需要能夠解密數據(不是很難,但是不必要的復雜性)

將未加密的數據放在cookie中並不是最好的,除了cookie中的任何內容之外,還可以為用戶添加額外帶寬使用量。

2)數據庫調用應該非常快,如果不是,那么無論如何你都會在其他地方遇到痛苦的用戶體驗。 換句話說,我強烈的觀點是,對於遠離cookie存在壓倒性的爭論。

考慮每次請求都會發送cookie; 它會更聰明,而不是將數據推入會話並增加開銷,在用戶發出請求后暫時(緩存)用戶數據加載,然后既沒有數據庫調用也沒有來自cookie的開銷而用戶主動在您的網站上。

老實說,一開始你應該沒有緩存。 專注於以最低的復雜性來提升您的應用程序。 這樣您就可以根據用戶反饋更快地修改它並減少錯誤。

3)當我玩護照時,我遇到了類似的問題。 我會讓護照完成它的工作,並向用戶授予護照級別的驗證(所以是的,他們已經登錄),然后單獨進行更多的數據收集。 如果您擔心安全問題,請將此護照級別的驗證未完全登錄,並在升級到完全登錄之前需要更多數據。

我可能與這個非常不合適,但這是我的建議。

4)當你有多個節點實例並希望將某些東西存儲在內存中時(例如計數器或緩存的用戶數據),Redis很適合。 這樣,您不會在節點代碼中保留有關用戶的緩存數據的變量,當用戶返回並且負載均衡器將其射向另一個實例時,另一個節點實例無法利用該變量。 http://www.ourdailycodes.com/2013/09/redis-when-should-i-use-it.html

編輯:我應該添加該會話使用cookie,但只給用戶一個服務器理解的唯一令牌,以便服務器可以在收到連接並附帶會話令牌時重新收集用戶的會話數據。 我的理解是,這是Session工作的一般正確方式......但它因實現而異(如果我在這里錯了,有人會糾正我)。

我用了node.js這是文檔中的代碼:

passport.serializeUser(function(user, done) {
   done(null, user.id);
});

passport.deserializeUser(function(id, done) {
   User.findById(id, function (err, user) {
        done(err, user);
   });
});

這是代碼,我修改為更好地理解:

var passport = require ('passport')
passport.serializeUser (function(user, done) {
   done(null, user.id);
});

passport.deserializeUser(function(id, done) {
   var user = _.find(fixtures.users, 'id', id)
       if (user) {
          done (null, user);
       }
       else
          { done (null, false) }
});


module.exports = passport;

在serializeUser中,客戶端發送帶有“id”的cookie。 serializeUser中的'(user)'參數是用戶配置文件,客戶端僅使用用戶配置文件中的'id'向服務器發送請求。 完成回調將user.id傳遞給服務器。

在deserializedUser中,服務器將查看數據庫並從serializedUser中找到具有該“id”的用戶並返回用戶配置文件。 我使用'lodash'來使用find和remove方法。

var _ = require ('lodash')
var user = _.find(fixtures.users, 'id', id)

find將查找用戶ID並返回具有該id的用戶配置文件。 關於lodash的更多細節在這里: lodash 之后我檢查用戶是否存在然后返回用戶否則返回false。

最后,我出口護照。

module.exports = passport;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM