node.js - 使用 Passport-jwt 进行 Node JS 身份验证未经授权

标签 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);

我想使用 Passport 和 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.'});
                }
            });
        }
    });
});

postman 的一切都很好。 token 已正确生成并使用用户信息进行签名。

但是我在 protected 路由上进行身份验证时遇到问题:

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 但它也不起作用......

最佳答案

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

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

关于node.js - 使用 Passport-jwt 进行 Node JS 身份验证未经授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45921909/

相关文章:

javascript - 如何使用 expressjs 写入 HTML 文件

node.js - npm install 忽略自己的 ssh+git 存储库

mongodb - 使用 Mongoose 搜索用户

node.js - Passportjs 本地策略缺少凭据错误消息

passport.js - Passport - Azure AD - 此 API 版本不支持应用程序

node.js - 没有 Java 的 JSDoc?

javascript - 如何从nodejs中的外部url检索DOM对象

ruby-on-rails - 未初始化的常量 devise::controllers::internalhelpers

javascript - 在 Angular2 中实现基于角色的访问

c# - 具有 SSL 和用户名和密码身份验证的自托管 WCF 服务