【问题标题】:Hot to set authentication in passport-jwt with different role of user?使用不同的用户角色在passport-jwt中设置身份验证很热门?
【发布时间】:2019-04-30 12:42:54
【问题描述】:

我正在尝试添加一个名为 admin 的角色来验证登录到仪表板 Web 应用程序的管理员,而普通用户只能访问常规页面。

对于普通用户,我需要server.js中的护照喜欢

// use passport 
app.use(passport.initialize());
require("./config/passport")(passport);

config/passport.js,像官方例子中的代码,我试试这个:

const JwtStrategy = require('passport-jwt').Strategy,
ExtractJwt = require('passport-jwt').ExtractJwt;
const mongoose = require('mongoose');
const User = mongoose.model("users");
const key  =require("../config/key");

const  opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = key.secretKey;

module.exports = passport => {
    passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
        // console.log(jwt_payload);
        User.findById(jwt_payload.id)
            .then(user => {
                if(user) {
                    return done(null, user);
                }

                return done(null, false);
            })
            .catch(err => console.log(err));
    }));
};

这种方式效果很好,我在路线中使用它们

router.get("/current", passport.authenticate("jwt", {session: false}), (req, res) => {
    res.json({
        id: req.user.id,
        name: req.user.name,
        username: req.user.username,
        email: req.user.email,
        avatar: req.user.avatar,
    });
}) 

但是,当我在令牌规则中添加角色时:

const rule = {id:admin.id, email: admin.email, avatar: admin.avatar, admin: admin.admin};

如何检查 admin 属性是否为 true 以查询 passport.js 中的不同集合

我试过这个,这对我不起作用,错误似乎服务器运行了两次:

module.exports = passport => {
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
    // console.log(jwt_payload);
    if(jwt_payload.admin){
        Admin.findById(jwt_payload.id)
        .then(user => {
            if(user) {
                return done(null, user);
            }

            return done(null, false);
        })
        .catch(err => console.log(err));
    } else {
    User.findById(jwt_payload.id)
        .then(user => {
            if(user) {
                return done(null, user);
            }

            return done(null, false);
        })
        .catch(err => console.log(err));
    }
}));};

错误是: Error

【问题讨论】:

    标签: node.js passport-jwt


    【解决方案1】:

    这就是我所做的,它工作得很好......我只是在我的用户模型中包含isAdmin: Boolean,如下所示:

    const userSchema = new mongoose.Schema({
      name: {
        type: String,
        required: true,
        minlength: 5,
        maxlength: 50
      },
      email: {
        type: String,
        required: true,
        minlength: 5,
        maxlength: 255,
        unique: true
      },
      password: {
        type: String,
        required: true,
        minlength: 5,
        maxlength: 1024
      },
      isAdmin: Boolean
    });
    

    然后像这样将它包含在 jwt 中:

    userSchema.methods.generateAuthToken = function() { 
      const token = jwt.sign({ _id: this._id, isAdmin: this.isAdmin }, config.get('jwtPrivateKey'));
      return token;
    }
    

    然后是一个自定义中间件来检查 isAdmin 的值,如下所示:

    module.exports = function (req, res, next) { 
      if (!req.user.isAdmin) return res.status(403).send('Access denied.');
      next();
    }
    

    然后我只需导入它并将其用作任何路线的第二个参数,如下所示:

    router.patch('/:id', [auth, isAdmin, validateObjectId], async (req, res) => {
      // handle the route (in order to do anything in this route you would need be an admin...)
    });
    

    编辑:如果您对这里的其他两个中间件感到好奇,它们就是......

    auth.js:

    const jwt = require('jsonwebtoken');
    const config = require('config');
    
    module.exports = function (req, res, next) {
      const token = req.header('x-auth-token');
      if (!token) return res.status(401).send('Access denied. No token provided.');
    
      try {
        const decoded = jwt.verify(token, config.get('jwtPrivateKey'));
        req.user = decoded; 
        next();
      }
      catch (ex) {
        res.status(400).send('Invalid token.');
      }
    }
    

    验证对象ID:

    const mongoose = require('mongoose');
    
    module.exports = function(req, res, next) {
      if (!mongoose.Types.ObjectId.isValid(req.params.id))
        return res.status(404).send('Invalid ID.');
    
      next();
    }
    

    【讨论】:

    • 这是中间件的第二个参数列表吗? 'auth' 可以改成普通的用户认证,然后一起使用自定义的中间件?
    • 第二个参数是数组 [auth, isAdmin, validateObjectId]... 数组中的每个元素都是中间件 auth 是 jwt.verify 中间件,isAdmin 是我向您展示的,validateObjectId 是正是它所说的......所有 3 个都是我作为第二个参数传递的中间件......如果你很好奇,我可以编辑我的帖子以包含这两个中间件......
    猜你喜欢
    • 2016-01-02
    • 1970-01-01
    • 2019-03-28
    • 2020-01-25
    • 2017-05-13
    • 2019-03-30
    • 1970-01-01
    • 2017-11-17
    • 2014-11-14
    相关资源
    最近更新 更多