【问题标题】:passport-local with node-jwt-simple使用 node-jwt-simple 的本地护照
【发布时间】:2013-12-12 06:35:25
【问题描述】:

如何结合本地护照以在成功验证时返回 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?
}

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

【问题讨论】:

    标签: node.js authentication token jwt passport.js


    【解决方案1】:

    我想通了!

    首先,您需要实施正确的策略。在我的例子中是 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)时,上面的第一个代码 sn-p 将尝试根据您提供的用户名查找用户,然后检查密码是否匹配(当然您会需要更改它以满足您的需求)。

    之后,您的登录路由将被调用,您可以在此处处理返回错误或有效令牌。

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

    【讨论】:

    • Passport 的 BasicStrategy 或 DigestStrategy 是另外两个选项。不过,Basic 和 Local 策略之间似乎没有太大区别,因为两者都不需要会话来工作 - 只是 Local 要求重定向 URL(使其 API 友好度稍低)。
    • 嘿@cgiacomi 你能举一个检查令牌的路线的例子吗?
    • 嘿@matt-kim 实际上我不保存令牌,它是暂时的。我不知道这是否是最好的方法,但这就是我所做的:用户进行身份验证,我生成令牌并将其返回给客户端。如果客户端是网站,则令牌存储在 localStorage 中,或者您可以将其存储在 iPhone/Android 应用程序中。当客户端必须请求资源时,它会将保存的令牌发送到后端。 Passport 将处理令牌。这是处理令牌gist.github.com/cgiacomi/cd1efa187b8cccbe2a61 的承载策略的要点,希望对您有所帮助! :)
    • 嘿@cgiacomi!也许这很明显,但是您能描述一下在使用自定义回调时如何禁用会话吗?
    • @MrMuh 在我的评论中查看链接gist.github.com/cgiacomi/cd1efa187b8cccbe2a61 我展示了如何禁用会话:passport.authenticate('bearer', { session: false })
    【解决方案2】:

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

    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/

    【讨论】:

    • 我只使用express-jwt 进行身份验证,但阅读其他包的文档,例如passport-jwt,我想我会坚持使用express-jwt。更简单,更好的 IMO
    • 仅供参考 express-jwt 不提供对刷新令牌的支持。
    【解决方案3】:

    这是我正在专门为仅使用 api 令牌而开发的样板(没有会话...当然不是那个会话不好;只是我们正在使用令牌方法): https://github.com/roblevintennis/passport-api-tokens

    【讨论】:

      猜你喜欢
      • 2019-06-23
      • 2023-04-06
      • 2019-05-23
      • 2022-11-04
      • 2018-04-21
      • 2016-05-09
      • 2018-01-13
      • 2020-03-08
      • 1970-01-01
      相关资源
      最近更新 更多