2013-03-29 98 views
55

我已經看過如何通過this stack exchange錯誤處理應該在節點中工作,但我不確定什麼護照在身份驗證失敗時正在做什麼。我有以下LocalStrategy:Express Passport(node.js)錯誤處理

passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, 
    function(email, password, next) { 

    User.find({email: UemOrUnm}, function(err, user){ 
     if (err) { console.log('Error > some err'); return next(err); } 
     if (!user) { console.log('Error > no user'); return next('Incorrect login or password'); } 

     if (password != user.password) { 
     return next(Incorrect login or password); 
     } 
     return next(null, user); 
    }); 
    } 
)); 

後,我看到「錯誤>一些ERR」控制檯打印輸出,沒有什麼事情發生。我認爲它應該繼續在下一個錯誤參數的路徑,但它似乎並沒有這樣做。這是怎麼回事?

回答

135

策略實施與passport.authenticate一起使用,以驗證請求並處理成功/失敗。

說你正在使用這條路線(這是通過一個電子郵件地址和密碼):

app.post('/login', passport.authenticate('local', { 
    successRedirect: '/loggedin', 
    failureRedirect: '/login', // see text 
    failureFlash: true // optional, see text as well 
}); 

這將調用代碼的戰略,其中的三個條件之一可能發生:

  1. 嘗試獲取用戶信息時發生內部錯誤(比如說數據庫連接已經消失);這個錯誤將被傳遞:next(err);這將由Express處理並生成HTTP 500響應;
  2. 提供的憑證無效(沒有提供電子郵件地址的用戶,或者密碼不匹配);在這種情況下,您不會生成錯誤,但是您將通過false作爲用戶對象:next(null, false);這將觸發failureRedirect(如果您沒有定義一個,則會生成HTTP 401 Unauthorized響應);
  3. 一切都檢出,你有一個有效的用戶對象,所以你傳遞它:next(null, user);這將觸發successRedirect;

在一個無效的認證(但不是一個內部錯誤)的情況下,你可以用回調一起傳遞一個額外的消息:

next(null, false, { message : 'invalid e-mail address or password' }); 

如果你已經使用failureFlash安裝the connect-flash middleware中,提供的消息存儲在會話中,並且可以輕鬆訪問,例如,可以在模板中使用。

編輯:它也可以完全處理身份驗證過程自己的結果(而不是護照發送重定向或401):

app.post('/login', function(req, res, next) { 
    passport.authenticate('local', function(err, user, info) { 
    if (err) { 
     return next(err); // will generate a 500 error 
    } 
    // Generate a JSON response reflecting authentication status 
    if (! user) { 
     return res.send({ success : false, message : 'authentication failed' }); 
    } 
    // *********************************************************************** 
    // "Note that when using a custom callback, it becomes the application's 
    // responsibility to establish a session (by calling req.login()) and send 
    // a response." 
    // Source: http://passportjs.org/docs 
    // *********************************************************************** 
    req.login(user, loginErr => { 
     if (loginErr) { 
     return next(loginErr); 
     } 
     return res.send({ success : true, message : 'authentication succeeded' }); 
    });  
    })(req, res, next); 
}); 
+2

謝謝!我想在我的情況下,我試圖通過ajax發送失敗的響應,而不是做重定向。看看護照文檔,我認爲這意味着我必須使用自定義函數回調來格式化我的路線。 –

+3

如果有幫助,我編輯了我的答案,以顯示自己處理身份驗證的可能方式:) – robertklep

+1

感謝您的「自己處理身份驗證」編輯,這是一種拯救生命! – wulftone

2

您需要添加req.logIn(function (err) { });,做成功重定向內回調函數

+0

你能說清楚你的答案嗎? – dgilperez

15

什麼基督徒說的話是你需要添加功能

req.login(user, function(err){ 
    if(err){ 
    return next(err); 
    } 
    return res.send({success:true}); 
}); 

所以整個路線將是:

app.post('/login', function(req, res, next) { 
    passport.authenticate('local', function(err, user, info) { 
    if (err) { 
     return next(err); // will generate a 500 error 
    } 
    // Generate a JSON response reflecting authentication status 
    if (! user) { 
     return res.send(401,{ success : false, message : 'authentication failed' }); 
    } 
    req.login(user, function(err){ 
     if(err){ 
     return next(err); 
     } 
     return res.send({ success : true, message : 'authentication succeeded' });   
    }); 
    })(req, res, next); 
}); 

來源:http://passportjs.org/guide/login/