使用passport-jwt的节点JS身份验证未经授权

时间:2017-08-28 14:56:44

标签: node.js authentication passport.js json-web-token

我正在尝试设置我的Node JS API。

我有一个用户模型:

// Dependencies
var restful = require('node-restful');
var mongoose = restful.mongoose;

var bcrypt = require('bcrypt');

// Schema
var userSchema = new mongoose.Schema({
    username: {
        type: String, 
        required: true, 
        unique: true},
    firstname: {
        type: String, 
        required: true
    },
    lastname: {
        type: String, 
        required: true
    },
    email: {
        type: String, 
        required: true, 
        unique: true,
        lowercase: true
    },
    password: {
        type: String, 
        required: true},
},
{
    timestamps: true
});

// Saves the user's password hashed
userSchema.pre('save', function (next) {  
  var user = this;
  if (this.isModified('password') || this.isNew) {
    bcrypt.genSalt(10, function (err, salt) {
      if (err) {
        return next(err);
      }
      bcrypt.hash(user.password, salt, function(err, hash) {
        if (err) {
          return next(err);
        }
        user.password = hash;
        next();
      });
    });
  } else {
    return next();
  }
});


// Use bcrypt to compare passwords
userSchema.methods.comparePassword = function(pw, cb) {  
  bcrypt.compare(pw, this.password, function(err, isMatch) {
    if (err) {
      return cb(err);
    }
    cb(null, isMatch);
  });
};

module.exports = restful.model('Users', userSchema);

我想使用带有jwt的护照进行身份验证:

// Dependencies
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var config = require('../config/database');

// Load models
var User = require('../models/user');

// Logique d'authentification JWT
module.exports = function(passport) {  
  var opts = {};
  opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('JWT');
  opts.secretOrKey = config.secret;
  opts.audience = 'localhost';

  passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
    User.findById(jwt_payload._id, function(err, user) {
      if (err) {
        return done(err, false);
      }
      if (user) {
        done(null, user);
      } else {
        done(null, false);
      }
    });
  }));
  passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
    Company.findById(jwt_payload._id, function(err, company) {
      if (err) {
        return done(err, false);
      }
      if (company) {
        done(null, company);
      } else {
        done(null, false)
      }
    });
  }));
};

我的身份验证路线:

// User
router.post('/users/login', (req, res) => {
    User.findOne({
        email: req.body.email
    }, (err, user) => {
        if (err) throw err;

        if (!user) {
            res.json({success: false, message: 'Authentication failed. User not found.'});
        } else {
            // Check if passwords matches
            user.comparePassword(req.body.password, (err, isMatch) => {
                if (isMatch && !err) {
                    // Create token if the password matched and no error was thrown
                    var token = jwt.sign(user, config.secret, {
                        expiresIn: 10080 // in seconds
                      });
                    res.json({success: true, token: 'JWT ' + token, user: {
                        id: user._id,
                        username: user.username,
                        email: user.email
                    }});    
                } else {
                    res.json({success: false, message: 'Authentication failed. Passwords did not match.'});
                }
            });
        }
    });
});

邮递员的一切都很棒。 令牌已正确生成并使用用户的信息进行签名。

但我在受保护路由上的身份验证存在问题:

router.get('/users/profile', passport.authenticate('jwt', { session: false }), function(req, res) {  
    res.send('It worked! User id is: ' + req.user._id + '.');
  });

每次,它都会给我一个"未经授权的401"错误。

我真的不知道问题出在哪里,我认为问题出在jwtFromRequest附近,我也尝试过Bearer,但它也没有工作......

1 个答案:

答案 0 :(得分:1)

我认为避免此类问题的一个很好的选择是从使用此身份验证策略的基础项目开始,并在完成后,使用您的功能对其进行修改。

这里有一个jwt认证策略和刷新令牌实现的例子:https://solidgeargroup.com/refresh-token-autenticacion-jwt-implementacion-nodejs?lang=es