节点 passport-jwt 从令牌中提取错误的用户

Node passport-jwt extracting wrong user from token

我的代码中遇到了一个奇怪的错误或错误。 我在节点服务器上设置了一个身份验证 api,使用 passportjs 作为我的中间件和 passport-jwt 作为我的策略。

我的护照设置如下所示

//add jwt strategy to passport
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;

var User = require('../models/user');
var configDB = require('../config/database');

module.exports = function(passport) {
    var opts = {};
    opts.secretOrKey = configDB.secret;
    opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
    passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
        //find user with give jwt payload id
        User.findOne({
            id: jwt_payload.id
        }, function(err, user) {
            if(err) {
                return done(err, false);
            }
            if(user) {
                done(null, user);
            } else {
                done(null, false);
            }
        });
    }));
};

那么,我的保护路线:

apiRoutes.get('/account', passport.authenticate('jwt', {session: false}), function(req, res) { 

    console.log(req.user.nickname); //returns user1 no matter what JWT I supply with request
    console.log(jwt.decode(getToken(req.headers), configDB.secret)).nickname; //decodes user from token correctly
    ..do other stuff
});

为什么无论我在 Authorization header 中提供什么 Token,passport 每次都将 req.user 设置为同一个用户? 谢谢

已解决, 此行导致问题:

User.findOne({
  id: jwt_payload.id
...

两个id都应该是_id :)

@BlueBallPanda,用 passport.js JWT 身份验证策略回答你的问题我想展示你在行中使用的 JWT_PAYLOAD 对象的结构:

...  
passport.use(new JwtStrategy(opts, function(jwt_payload, done) { 
...
}));

作为参考示例,下面是JWT_PAYLOAD对象的输出,可以看到它的结构,其实很容易混淆:

JWT_PAYLOAD:  { '$__':
   { strictMode: true,
     selected: {},
     getters: {},
     _id: '7987930e36333b5634bb5577',
     wasPopulated: false,
     activePaths: { paths: [Object], states: [Object], stateNames: [Array] },
     pathsToScopes: {},
     emitter: { domain: null, _events: {}, _eventsCount: 0, _maxListeners: 0 } },
  isNew: false,
  _doc:
   { __v: 0,
     password: 'aGRB1vGbkl3XfGY.r81SuASyK/cfsp85fk92B3N6eSRO6GVy1TSW',
     email: 'example.mail@email.com',
     _id: '7987930e36333b5634bb5577' },
  '$init': true,
  iat: 1502061031,
  exp: 1502071111 }

所以为了在 JWT 检查中从数据库中提取用户 ID, 就这样引用它:

 User.findOne({
        id: jwt_payload.$__._id
    }

或类似的:

 User.findOne({
        id: jwt_payload.$__._doc._id
    }

希望这能解决您遇到的问题。

我用这个函数解决了这个问题:

var JwtStrategy = require(‘passport-jwt’).Strategy,
ExtractJwt = require(‘passport-jwt’).ExtractJwt;

// load up the user model
var User = require(‘../models/user’);
var config = require(‘../config/database’); // get db config file

module.exports = function(passport) {
    var opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
    opts.secretOrKey = config.secret;
    passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
        done(null, jwt_payload._doc);
    }));
};

_doc 有资料使用者。

添加 where 子句解决了我的问题:

let user = await User.findOne({ where: { id: JWTPayloads.id } });