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

时间:2016-09-26 14:53:30

标签: node.js passport.js jwt

我的代码中遇到了一个奇怪的错误或错误。 我在节点服务器上设置了auth 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
});

为什么护照每次都为同一个用户设置req.user,无论我在Authorization标头中提供什么令牌? 感谢

4 个答案:

答案 0 :(得分:2)

解决, 这一行造成了问题:

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

两个ID都应该是_id :)

答案 1 :(得分:2)

@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: '$2a$10$12GRB1vGbkl3XfGY.r81SuASyK/cfsp85fk92B3N6eSRO6GVy1TSW',
     email: 'example.mail@email.com',
     _id: '7987930e36333b5634bb5577' },
  '$init': true,
  iat: 1502061031,
  exp: 1502071111 }

所以要抓取用户ID以便在JWT检查中从数据库中提取, 就像那样引用它:

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

或者那样:

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

希望这可以清除您遇到的错误情况。

答案 2 :(得分:0)

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

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有数据用户。

答案 3 :(得分:0)

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

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