设置 passport-jwt 身份验证

Posted

技术标签:

【中文标题】设置 passport-jwt 身份验证【英文标题】:Setting up passport-jwt authentication 【发布时间】:2016-01-02 14:56:06 【问题描述】:

我在使用 express api 服务器设置 passport-jwt 时遇到了一些问题。

在前端,我使用ember.js 将应验证会话的凭据发布到/auth 路由,然后ember.js 中的库将处理在后续请求中发送令牌。

我松散地关注this tutorial,并用passport-jwt 替换了他们的passport-http,并使用the git repo 中的示例进行设置。

在我的server.js 中,我需要护照并使用app.use(passport.initialize()); 将其设置为中间件

server.js 文件的底部,我用app.use('/api/v1', '/app/routes/api'); 调用我的api 路由文件

我的app/routes/api.js 文件看起来有一个部分用于添加和获取这样的用户

router.route('/users')
  .post(function(req,res)  user.addUser(req,res) )
  .get(function(req,res)  user.getAllUsers(req,res) );

哪些是对 api/user.js 文件中导出的引用,如下所示

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

module.exports.addUser = function(req, res) 
  var user = new User(req.body.user);

  user.save(function(err) 
    if (err)
      res.send(err);
    res.json(user: user);
  );
;

module.exports.getAllUsers = function(req, res) 
  User.find(function(err, users) 
      if (err) 
        res.send(err);
      
      res.json(users: users);
  );
;

该模型非常简单,它会尝试在密码未更改的情况下在保存时对密码进行哈希处理(我假设这是针对PUT 请求)以及密码验证类方法

var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');

var UserSchema = new mongoose.Schema(
    username: 
        type: String,
        unique: true,
        required: true
    ,
    password: 
        type: String,
        required: true
    
);

UserSchema.pre('save',function(callback)
    var user = this;

    if(!user.isModified('password')) return callback();

    bcrypt.genSalt(5, function(err, salt)
        if (err) return callback(err);

        bcrypt.hash(user.password, salt, null, function(err, hash)
            if (err) return callback(err);
            user.password = hash;
            callback();
        );
    );
);

UserSchema.methods.verifyPassword = function(password) 
  return bcrypt.compareSync(password, this.local.password);
;

module.exports = mongoose.model('User',UserSchema);

对于我的其他 API 端点,我从 controllers/auth.js 传递我的 isAuthenticated 方法,就像这样

router.route('/followers')
  .post(authController.isAuthenticated, function(req,res)  follower.addFollower(req,res) )
  .get(authController.isAuthenticated, function(req,res)  follower.getAllFollowers(req,res) );

控制器文件中的导出看起来像

var dotenv = require('dotenv');
dotenv.load();

var passport = require('passport');
var JWTStrategy = require('passport-jwt').Strategy;
var User = require('../models/user');

var opts = ;
opts.secretOrKey = process.env.PASSPORT_SECRET || 'secretsauce';
passport.use(new JWTStrategy(opts, function(jwt_payload, done)
    User.findOne(id: jwt_payload.sub, function(err, user)
        if (err) 
            return done(err, false);
        
        if (!user)  return done(null,false); 
        user.verifyPassword(password, function(err,isMatch)
            if (err)  return done(err, false); 
            if(!isMatch)  return done(null,false); 
            done(null, user);
        );
    );
));

exports.isAuthenticated = passport.authenticate('jwt',  session : false );

我认为这个区域是我对如何使用快速服务器进行身份验证感到困惑的地方。我可以添加用户并且他们的密码被正确地散列但是我如何实际验证用户。具体来说,我将如何在POST 上授权他们到/auth 路由?我正在使用邮递员来测试 API,所以如果有人可以解释如何在邮递员中使用 jwt 进行测试,那会很酷。我知道我必须为通过身份验证获得的令牌设置标头,但我不知道如何进行身份验证。

【问题讨论】:

我相信 passport-jwt 仅在您已经拥有令牌时才有效。您可能应该使用例如添加身份验证端点。 passport-local 通过用户名和密码验证用户,并给他们令牌。获得令牌后,只需在标头中传递它,passport-jwt 将处理其余部分。 啊,好吧,这可能解释了我在一些教程中看到的一些东西,其中包含了一些模块,但我并不真正理解它们是如何或为什么被包含在内的。 【参考方案1】:

在您的路线中,您应该包含用于检查是否存在有效令牌的 passport.authenticate 函数。

【讨论】:

以上是关于设置 passport-jwt 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Apollo 服务器 - 仅使用 Passport-JWT 将身份验证应用于某些解析器

对身份验证技术的怀疑 - 护照

使用不同的用户角色在passport-jwt中设置身份验证很热门?

使用 passport-jwt 验证节点 API

我在我的 nestJS 应用程序(使用 authGuard)中使用了 passport-jwt 身份验证策略,如何访问我的控制器中的令牌有效负载?

混合护照-facebook和passport-jwt的最佳方法是什么?