如何编写类似中间件的功能但可以具有一些参数

时间:2019-04-19 09:49:07

标签: node.js express

我想修改功能(checkAuth)以检查用户是否具有特定的权限。如果是=>继续,否则将打印错误。但是它返回“未定义”。 我想传递两个参数(userId和Permission_CODE)。我从解析令牌获得userId。 我使用了中间件,但似乎不允许传递其他参数(req,res,next除外)

这是用于运行NodeJS和Express的Windows服务器

checkToken.js

const jwt = require('jsonwebtoken');

module.exports = (req, res, next) => {
    try { 
        const token = req.headers.authorization.split(" ")[1];
        const decoded = jwt.verify(token, 'secretKey')
        req.decoded = decoded
        next();
    }
    catch(error){
        return res.status(401).json({
            message: "Auth failed"
        })
    }
}

checkAuth.js

const User = require('../models/user')

module.exports = (userId, action_code) => {
    User
        .findOne({ _id: userId })
        .populate({
            path: 'user_role',
            populate: {
                path: 'permissions',
                match: { action_code: action_code }
            }
        })
        .exec((err, user) => {
            if (err) {
                return console.log(err)
            }
            else if (user.user_role.permissions.length == 0) {
                return false
            }
            else {
                console.log(user.user_role.permissions)
                return true
            }
        })
}
}

在API中使用

router.get('/luu',checkToken,(req, res) => {
    console.log(checkAuth(req.decoded.userId, "1")) //It returned undefinded
})

这是程序的代码:https://github.com/phongluudn1997/express-testing.git

2 个答案:

答案 0 :(得分:0)

在checkAuth.js中,您的模块是异步的,因此,您不能只返回true / false,而必须在回调中返回结果。

module.exports = (userId, action_code, cb) => {
User
    .findOne({ _id: userId })
    .populate({
        path: 'user_role',
        populate: {
            path: 'permissions',
            match: { action_code: action_code }
        }
    })
    .exec((err, user) => {
        if (err) {
            return cb(err, false)
        }
        else if (user.user_role.permissions.length == 0) {
            return cb(null, false);
        }
        else {
            console.log(user.user_role.permissions)
            return cb(null, true);
        }
    })
}
}

并且您必须像这样调用模块:

router.get('/luu',checkToken,(req, res) => {
    checkAuth(req.decoded.userId, "1", function(err, result){

       if(err) console.log(err);
       else if(!result) console.log("False");
       else console.log("True");
    });
})

答案 1 :(得分:0)

您正试图从无效的回调中返回。您可以像这样使用async/await

module.exports = async (userId, action_code) => {
  let permission;
  try {
    const user = await User
      .findOne({ _id: userId })
      .populate({
      path: 'user_role',
      populate: {
        path: 'permissions',
        match: { action_code: action_code }
      }
    })
    if (user.user_role.permissions.length == 0) {
      permission = false
    } else {
      console.log(user.user_role.permissions)
      permission = true
    }
  } catch (e) {
    throw e
  }
  return permission
}

使路线async也起作用:

router.get('/luu',checkToken, async (req, res) => {
  try {
    console.log(await checkAuth(req.decoded.userId, "1"))
  } catch (e) {
    console.error(e)
  }
})

或使其成为另一个中间件功能,例如:

// checkPermission.js
module.exports = (req, res, next) => {
  User
    .findOne({ _id: userId })
    .populate({
    path: 'user_role',
    populate: {
      path: 'permissions',
      match: { action_code: action_code }
    }
  })
    .exec((err, user) => {
    if (err) {
      return next(err)
    }
    else if (user.user_role.permissions.length == 0) {
      req.permissions = false
    }
    else {
      console.log(user.user_role.permissions)
      req.permissions = true
    }
  })
  next();
}

然后在您的路线上

const checkPermission = require('./checkPermission.js')

router.get('/luu',checkToken, checkPermission, (req, res) => {
  console.log(req.permissions)
})