带有node-jwt-simple的本地护照

cgi*_*omi 87 authentication token node.js jwt passport.js

如何在本地身份验证后,将本地护照与JWT令牌结合使用?

我想使用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);
    });
  }
));
Run Code Online (Sandbox Code Playgroud)

调用done()时是否可以返回令牌?像这样......(只是伪代码)

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

如果没有,我该如何退回令牌?

cgi*_*omi 122

我想到了!

首先,您需要实施正确的策略.在我的案例中,LocalStrategy,您需要提供验证逻辑.例如,让我们使用护照本地的那个.

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);
    });
  }
));
Run Code Online (Sandbox Code Playgroud)

您提供的验证回叫function(username, password, done)将负责找到您的用户并检查密码是否匹配(超出问题范围和我的答案)

passport.js期望它可以运行几个部分,一个是你在策略中返回用户.我试图改变代码的那一部分,这是错误的.回调期望false验证失败,并且object(如果验证的用户)成功.

现在....如何整合JWT?

在您的登录路线中,您将必须处理成功的身份验证或不成功的身份验证.在这里,您需要添加JWT令牌创建.像这样:

(记得要禁用会话,否则你将不得不实现序列化和反序列化功能.如果你没有持久化会话你不需要那些,如果你使用的是基于令牌的身份验证,则不需要这些功能)

来自护照本地示例:(添加了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);
});
Run Code Online (Sandbox Code Playgroud)

就是这样!现在,当您调用/ login和POST用户名和密码(应始终通过SSL)时,上面的第一个代码片段将尝试根据您提供的用户名查找用户,然后检查密码是否匹配(当然您需要改变它以满足您的需求).

之后,将调用您的登录路由,在那里您可以负责返回错误或有效令牌.

希望这会对某人有所帮助.如果我犯了任何错误或遗忘了某些事情,请告诉我.

  • Passport的[BasicStrategy](http://passportjs.org/guide/basic-digest/)或DigestStrategy是另外两个选项.但是,基本策略和本地策略之间似乎没有太大的区别,因为它们都不需要会话才能工作 - 只需要本地请求重定向URL(使其稍微不那么友好). (3认同)
  • 嘿@ matt-kim实际上我不保存令牌,它是短暂的.我不知道它是否是最佳方式,但这就是我所做的:用户进行身份验证,然后生成令牌并将其返回给客户端.如果客户端是网站,则令牌存储在localStorage中,或者您可以将其存储在iPhone/Android应用程序中.当客户端必须发出资源请求时,它会将保存的令牌发送到后端.Passport将处理令牌.以下是处理令牌的持票人策略的要点https://gist.github.com/cgiacomi/cd1efa187b8cccbe2a61希望这有帮助!:) (3认同)
  • 很酷,感谢您发布如何解决它:) (2认同)
  • 嘿@cgiacomi,你能给出一个检查令牌的路由示例吗? (2认同)
  • 嘿@cgiacomi!也许这是显而易见的,但是您能描述一下在使用自定义回调时如何禁用会话吗? (2认同)
  • @MrMuh在我的评论中查看链接https://gist.github.com/cgiacomi/cd1efa187b8cccbe2a61我将展示如何禁用会话:passport.authenticate('bearer',{session:false}) (2认同)

小智 18

这是一个很好的解决方案,我只想添加:

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

app.use('/api', expressJwt({secret: secret}));
Run Code Online (Sandbox Code Playgroud)

我喜欢使用"express-jwt"来验证令牌.

顺便说一句:这篇文章非常适合学习如何使用Angular在客户端处理令牌,以便在每次请求时将其发回

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

  • 我只使用`express-jwt`来进行身份验证,但是阅读其他软件包的文档,例如`passport-jwt`,我想我会坚持使用`express-jwt`.更简单,更好的IMO (2认同)