【问题标题】:passport-jwt 401 Unauthorized护照-jwt 401 未经授权
【发布时间】:2018-02-04 10:15:32
【问题描述】:

我正在尝试实现 passport-jwt 身份验证,但在尝试调用端点时总是得到 401 Unauthorized。

这是我的设置

passport.js

var passport = require('passport');
var User = require('../models/user');
var config = require('./auth');
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var LocalStrategy = require('passport-local').Strategy;

var localOptions = {
    usernameField: 'email'
};

var localLogin = new LocalStrategy(localOptions, function(email, password, done) {

    User.findOne({
        email: email
    }, function(err, user) {
        if (err) {
            return done(err);
        }
        if (!user) {
            return done(null, false, { error: 'Login failed. Please try again' });
        }

        user.comparePassword(password, function(err, isMatch) {
            if (err) {
                return done(err);
            }
            if (!isMatch) {
                return done(null, false, { error: 'Login Failed. Please try again.' });
            }

            user.status = 'online';
            user.save(function(err, user) {
                if (err) {
                    return done(err);
                }
            });

            return done(null, user);
        });
    });
});

var jwtOptions = {
    jwtFromRequest: ExtractJwt.fromHeader('Authorization'),
    secretOrKey: config.secret
};

var jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {
    console.log(payload);
    User.findById(payload._id, function(err, user) {
        if (err) {
            return done(err, false);
        }
        if (user) {
            done(null, user)
        } else {
            done(null, false);
        }
    });
});

passport.use(localLogin);
passport.use(jwtLogin);

module.exports = {
    initialize: () => passport.initialize(),
    authenticateJWT: passport.authenticate('jwt', { session: false }),
    authenticateCredentials: passport.authenticate('local', { session: false }),
};

user.js

var express = require('express');
var router = express.Router();
var AuthController = require('../controllers/authentication');
var passportService = require('../config/passport');
var passport = require('passport');

const requireToken = passportService.authenticateJWT;
const requireCredentials = passportService.authenticateCredentials;


router.post('/signup', AuthController.register);
router.post('/signin', requireCredentials, AuthController.login);

router.get('/protected', requireToken function(req, res, next){
res.send({msg:'Success!'});
});

module.exports = router;

我已确保我的标头包含:'JWT' + [some token]... 也试过没有'JWT'仍然什么都没有......

我已经检查过其他帖子关于同样的问题,但仍然无法解决。

【问题讨论】:

标签: node.js authentication jwt passport.js


【解决方案1】:

简短
旧版
'JWT ' + [some token]

版本 0.4.0
'bearer ' + [some token]

示例
所以当你现在发送令牌时是这样的:
旧版
res.json ({ success: true, token: 'JWT ' + token })

版本 0.4.0
res.json ({ success: true, token: 'bearer ' + token })

深入
可能还有其他方法可以做到这一点
如果您查看/node_module/passport-jwt/lib/extract_jwt.js 文件,您可以看到有一个名为versionOneCompatibility(options) 的函数

【讨论】:

  • 我用过同样的,但它也不能解决我使用 V4.0.0 的问题,你能详细说明如何添加这个令牌作为响应,或者如果可能的话请创建演示
【解决方案2】:

经过数小时的尝试,我终于通过使用ExtractJwt.fromAuthHeaderWithScheme('Bearer') 方法解决了这个问题。由于某种原因,提取器无法使用其他方法获取令牌。

【讨论】:

    【解决方案3】:

    我遇到了同样的问题,经过研究,我发现了导致此问题的原因。 当您在路线内创建 res.json 时

    //Authenticate
    router.post('/authenticate', (req, res, next) => {
      const username = req.body.username;
      const password = req.body.password;
    
      User.getUserByUsername(username, (err, user) => {
        if (err) throw err;
        if (!user) {
          return res.json({
            success: false,
            msg: 'User not found'
          });
        }
    
        User.comparePassword(password, user.password, (err, isMatch) => {
          if (err) throw err;
          if (isMatch) {
            const token = jwt.sign(user.toJSON(), config.secret, {
              expiresIn: 604800 // 1 week
            });
            res.json({
              success: true,
              token: 'jwt ' + token, //Here you have to put space after name inside quotes
              user: {
                id: user._id,
                name: user.name,
                username: user.username,
                email: user.email
              }
            });
          } else {
            return res.json({
              success: false,
              msg: 'Wrong password'
            });
          }
        });
      });
    });

    在token里面:'jwt'+token,在jwt这个名字后面放一个空格很重要,还有你放在''引号里面的名字你必须把这个名字放在你的里面

    var opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt');//Here you have to put the same name inside quotes '' like you put inside token but without space after name
    opts.secretOrKey = config.secret;
    passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
        console.log(jwt_payload);
        User.findOne({
            id: jwt_payload.sub
        }, function(err, user) {
            if (err) {
                return done(err, false);
            }
    
            if (user) {
                return done(null, user);
            } else {
                return done(null, false);
            }
        });
    }));

    这两个要匹配,不管你放jwt还是jwt或者bearer或者其他什么,重要的是它们必须匹配,并且在创建token时必须有空格:'name '。

    【讨论】:

      猜你喜欢
      • 2017-10-18
      • 2018-05-19
      • 2018-03-18
      • 2019-02-01
      • 2019-08-29
      • 2021-09-24
      • 1970-01-01
      • 2018-06-06
      • 2021-09-21
      相关资源
      最近更新 更多