本地护照和node-jwt-simple


87

如何在成功进行身份验证时结合本地护照以返回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);
    });
  }
));

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

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

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

Answers:


123

我想到了!

首先,您需要实施正确的策略。就我而言,是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);
    });
  }
));

您提供的验证回电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);
});

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

之后,您的登录路由将被调用,在那里您可以照顾到返回错误或有效令牌。

希望这会帮助某人。如果我犯了任何错误或忘记了什么,请告诉我。


3
Passport的BasicStrategy或DigestStrategy是另外两个选项。不过,基本策略和本地策略之间似乎并没有太大的区别,因为它们都不需要会话才能工作-只是本地请求了重定向URL(这使得它对API的友好程度有所降低)。
funseiki 2014年

1
嘿@cgiacomi您能举一个检查令牌的路由示例吗?
马特·金

3
嘿@ matt-kim实际上我不保存令牌,这是暂时的。我不知道这是否是最好的方法,但这是我的工作:用户进行身份验证,然后生成令牌并将其返回给客户端。如果客户端是网站,则令牌存储在localStorage中,或者您可以将其存储在iPhone / Android应用中。当客户端必须请求资源时,它将已保存的令牌发送到后端。护照将处理令牌。这是一个采用Bearer策略处理令牌gist的要点 。github.com/cgiacomi/cd1efa187b8cccbe2a61 希望这会有所帮助!:)
cgiacomi 2014年

1
嘿@cgiacomi!也许很明显,但是您能描述一下使用自定义回调时如何禁用会话吗?
MrMuh 2014年

2
@MrMuh在我的评论中签出了gist.github.com/cgiacomi/cd1efa187b8cccbe2a61链接,我展示了如何禁用会话:passport.authenticate('bearer',{session:false})
cgiacomi 2014年

18

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

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

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

我喜欢使用“ express-jwt”来验证令牌。

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

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


2
我只用了 express-jwt做过身份验证,但是请仔细阅读其他软件包的文档,例如passport-jwt,我认为我会坚持使用express-jwt。IMO更简单,更好得多
bobbyz

仅FYI express-jwt不提供对刷新令牌的支持。
user3344977 16-10-21

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.