簡體   English   中英

如何在Node.js + MongoDB + PassportJS應用中執行異步身份驗證

[英]How to do asynchronous authentication in Node.js + MongoDB + PassportJS app

我正在使用Node.js,MongoDB和PassportJS,並且嘗試使用本地策略(僅使用簡單的ID和密碼)進行身份驗證。 問題在於,Mongo中的所有內容都是異步的,但是Passport是同步的。 我考慮過嘗試“鈎住”護照,以便我可以創建自己的回調,以便在Mongo回調返回后繼續進行身份驗證,但是我不知道護照代碼的工作原理(而且我還不十分希望啟動調試器並對其進行跟蹤)。

身份驗證過程實際上將成功完成,但不是在應用程序對客戶端做出響應之前完成,從而導致客戶端認為它仍未經身份驗證。 例如,在客戶端嘗試進行身份驗證之后,由於未對會話進行身份驗證,客戶端將被重定向回登錄表單。 如果我然后僅刷新頁面,我就會進入,因為到那時,身份驗證回調已經返回。

passport.use(new localAuth(function(username, password, done)
{
    process.nextTick(function()
    {
        mc.connect('mongodb://127.0.0.1:27017/example', function(err, db)
        {
            if(err)
                throw err;

            db.collection('users').findOne({GUID: username}, function(err, results)
            {
                if(err)
                    throw err;
                console.log('Here I am!');
                db.close();
                return done(null, username);
            });
        });
    });
}));

(我意識到上面的代碼沒有對任何內容進行身份驗證。我只是在嘗試通過異步方法進行工作。)

我已經在上面嘗試了多種不同的變體,但是它們都遇到了相同的問題:在我的數據庫查找有機會完成之前,賦予localAuth()的函數會返回,並且護照會繼續進行身份驗證。 我已經在SO上看到了幾個有關試圖迫使mongo同步工作的問題,而這些響應都是“不”的 我看到了這個問題 ,這確實是我的情況,並且我的方法是相同的,但是仍然存在在回調返回后需要刷新的問題。

我應該如何在node.js + mongoDB + Passport應用程序中執行身份驗證?

更新我注意到“我在這里!” 在第一次嘗試期間(即在刷新頁面之前)出現在日志中。 這使我認為身份驗證已完成,並且在第一次身份驗證嘗試期間設置了會話。 只是從localAuth()的回調( done() )返回的任何內容都不及時。 然后,當我刷新時,passport會嘗試獲取會話並看到它在那里。 這使我重新嘗試鈎住護照。 有人知道身份驗證期間何時調用new localAuth()嗎?

UPDATE

function authenticateUser(id, pass, cb)
{
console.log('1');
    mc.connect('mongodb://127.0.0.1:27017/sp2010sec', function(err, db)
    {
        if(err)
            throw err;

console.log('2');
        db.collection('users').findOne({GUID: id}, function(err, results)
        {
            if(err)
                throw err;
console.log('3');

            return cb(err, id);
        });
console.log('4');
    });
console.log('5');
}

passport.use(new localAuth(function(username, password, done)
{
console.log('6');
    authenticateUser(username, password, function(err, user)
    {
console.log('7');
        return done(err, username);
    });
console.log('8');
}));

上面的代碼生成此日志:

6

1

8

2

4

3

7

護照似乎沒有等待done呼叫。

我已經獲得了異步身份驗證的創可貼,所以我將解釋我的工作。 如果有人能給出更好的答案,我很想聽聽。

因此,問題在於mongoDB是異步的,但不是護照,而我能想到的一切都會導致護照在mongo回調返回之前對請求進行身份驗證(或者失敗)。 我嘗試了多種方法來鈎掛護照,以便直到完成mongo內容(某種預身份驗證)后,我才開始進行護照身份驗證,但是那也不起作用。 我認為這與護照的內部情況有關。

我最終要做的是在應用程序啟動時打開數據庫連接,並在應用程序的整個生命周期中保持打開狀態。 這減少了一個回調,我認為這是讓mongo回調及時完成,以便護照可以看到它。 這感覺像是潛在的比賽條件。 我希望看到一個比這個更好的答案,或者對真實情況進行解釋。

UPDATE

真正的問題是我沒有使用護照的成功/失敗重定向。 我在客戶端處理此問題,該客戶端在AJAX調用返回時就開始了(但未涉及護照回調鏈)。 一旦我開始在服務器端處理重定向,身份驗證就開始按預期/通告的方式工作。

我不認為您希望將用戶查找包裹在process.nextTick()調用中。 根據此答案 ,您只想在事件循環的下一次迭代中調用該代碼時才使用nextTick() 只需將其刪除即可解決問題。 這類似於發布在passport.js 指南上的代碼。

希望這可以幫助!

暫無
暫無

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

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