Как написать функцию вроде промежуточного программного обеспечения, но может иметь некоторые параметры - PullRequest
0 голосов
/ 19 апреля 2019

Я хочу изменить функцию (checkAuth), чтобы проверить, есть ли у пользователя определенные разрешения. Если да => продолжить, в противном случае будет напечатана ошибка. Но это возвращает «неопределенный». Я хочу передать два параметра (userId и Permission_CODE). Я получаю userId от разбора токена. Я использовал промежуточное ПО, но оно не позволяло передавать другие параметры (кроме req, res, next)

Это для сервера Windows, на котором запущены NodeJS и Express

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 голосов
/ 19 апреля 2019

Вы пытаетесь вернуться с обратного вызова, который не работает. Вы можете использовать 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)
})
0 голосов
/ 19 апреля 2019

В 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");
    });
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...