2013-11-26 39 views
81

如何結合passport-local在成功認證時返回JWT令牌?passport-local with node-jwt-simple

我想用node-jwt-simple並看着passport.js我不知道該怎麼去。

var passport = require('passport') 
    , LocalStrategy = require('passport-local').Strategy; 

passport.use(new LocalStrategy(
    function(username, password, done) { 
    User.findOne({ username: username }, function(err, user) { 
     if (err) { return done(err); } 
     if (!user) { 
     return done(null, false, { message: 'Incorrect username.' }); 
     } 
     if (!user.validPassword(password)) { 
     return done(null, false, { message: 'Incorrect password.' }); 
     } 
     return done(null, user); 
    }); 
    } 
)); 

調用done()時是否可以返回標記? 像這樣...(只是僞代碼)

if(User.validCredentials(username, password)) { 
    var token = jwt.encode({username: username}, tokenSecret); 
    done(null, {token : token}); //is this possible? 
} 

如果沒有,我怎麼可以返回令牌?

回答

116

我想通了!

首先您需要實施正確的策略。在我的情況LocalStrategy,你需要提供你的驗證邏輯。例如,讓我們使用passport-local中的那個。

var passport = require('passport') 
    , LocalStrategy = require('passport-local').Strategy; 

passport.use(new LocalStrategy(
    function(username, password, done) { 
    User.findOne({ username: username }, function(err, user) { 
     if (err) { return done(err); } 
     if (!user) { 
     return done(null, false, { message: 'Incorrect username.' }); 
     } 
     if (!user.validPassword(password)) { 
     return done(null, false, { message: 'Incorrect password.' }); 
     } 
     return done(null, user); 
    }); 
    } 
)); 

驗證回調您提供function(username, password, done)將找到你的用戶和檢查的護理如果密碼匹配(超出了問題的範圍和我的答案)

passport.js預計幾件吧工作,一個是你在戰略中回報用戶。我試圖改變那部分代碼,那是錯誤的。如果驗證失敗,則回調期望false,如果成功,則回調期望object(驗證的用戶)。

現在....如何整合智威湯遜?

在您的登錄路線中,您將不得不處理成功的身份驗證或不成功的身份驗證。在這裏您需要添加JWT令牌創建。像這樣:

(記住要禁用會話,否則你將不得不實現序列化和反序列化函數。如果你沒有保持會話,你不需要這些,如果你使用的是基於令牌身份驗證)

從Passport本地實例:(與JWT令牌加)

// POST /login 
// This is an alternative implementation that uses a custom callback to 
// achieve the same functionality. 
app.post('/login', function(req, res, next) { 
    passport.authenticate('local', function(err, user, info) { 
    if (err) { return next(err) } 
    if (!user) { 
     return res.json(401, { error: 'message' }); 
    } 

    //user has authenticated correctly thus we create a JWT token 
    var token = jwt.encode({ username: 'somedata'}, tokenSecret); 
    res.json({ token : token }); 

    })(req, res, next); 
}); 

,就是這樣!現在,當你打電話/登錄和POST用戶名和密碼(應始終通過SSL)上面的第一個代碼片段將嘗試根據您提供的用戶名找到用戶,然後檢查密碼是否匹配(當然,您需要改變以適應您的需求)。

之後,您的登錄路線將被調用,您可以在那裏處理返回錯誤或有效令牌。

希望這會幫助別人。如果我犯了錯誤或忘記了一些事情,請告訴我。

+2

酷,感謝張貼你如何解決它:) – robertklep

+3

Passport的[BasicStrategy](http://passportjs.org/guide/basic-digest/)或DigestStrategy是另外兩個選項。但是,基本策略和本地策略似乎並沒有太大區別,因爲這兩個策略都不需要會話 - 只需要本地請求重定向URL(使其略低於API)。 – funseiki

+1

嘿@cgiacomi你能舉一個檢查令牌的路線的例子嗎? –

18

這是一個很好的解決方案,我只想補充一點:

var expressJwt = require('express-jwt'); 

app.use('/api', expressJwt({secret: secret})); 

我喜歡用「表示,智威湯遜」驗證令牌。

BTW:這篇文章是偉大學習如何處理客戶端的令牌,採用了棱角分明,爲了把它送回來的每個請求

https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

+2

我只使用'express-jwt'來進行身份驗證,但通過其他軟件包的文檔閱讀,如'passport-jwt',我想我會堅持'express-jwt'。更簡單,更好用IMO – bobbyz

+0

只是FYI Express-jwt不提供刷新令牌的支持。 – user3344977