programing

매개 변수를 허용하는 expressjs 미들웨어 생성

javamemo 2023. 8. 8. 19:57
반응형

매개 변수를 허용하는 expressjs 미들웨어 생성

매개 변수를 허용할 수 있는 미들웨어를 만들려고 합니다.이것이 어떻게 행해지는가?

app.get('/hasToBeAdmin', HasRole('Admin'), function(req,res){

})

HasRole = function(role, req, res, next){
   if(role != user.role){
      res.redirect('/NotInRole);
   }

   next();
}
function HasRole(role) {
  return function(req, res, next) {
    if (role !== req.user.role) res.redirect(...);
    else next();
  }
}

또한 동일한 기능의 복사본을 여러 개 만들지 않아야 합니다.

function HasRole(role) {
  return HasRole[role] || (HasRole[role] = function(req, res, next) {
    if (role !== req.user.role) res.redirect(...);
    else next();
  })
}
app.get('/hasToBeAdmin', (req, res, next) => {
  hasRole(req, res, next, 'admin');
}, (req,res) => { 
    // regular route 
});

const hasRole = (req, res, next, role) => {
   if(role != user.role){
      res.redirect('/NotInRole');
   }
   next();
};

저는 이 용액을 사용합니다.나는 바디 요청에서 jwt 토큰을 받고 거기서 역할 정보를 얻습니다.

//roleMiddleware.js

const checkRole = role => {
    
    return (req, res, next) => {
        if (req.role == role) {
            console.log(`${role} role granted`)
            next()
        } else {
            res.status(401).send({ result: 'error', message: `No ${role} permission granted` })
        }
    }
}

module.exports = { checkRole }

먼저 auth 미들웨어를 사용하여 유효한 사용자인지 확인하고, 사용자가 api 경로에 액세스할 수 있는지 여부를 확인합니다.

// router.js

router.post('/v1/something-protected', requireAuth, checkRole('commercial'), (req, res) => {
    // do what you want...
})

나는 유용하기를 바랍니다.

또는 대소문자 수가 너무 많지 않거나 역할이 문자열이 아닌 경우:

function HasRole(role) {
  return function (req, res, next) {
    if (role !== req.user.role) res.redirect(/* ... */);
    else next();
  }
}

var middlware_hasRoleAdmin = HasRole('admin'); // define router only once

app.get('/hasToBeAdmin', middlware_hasRoleAdmin, function (req, res) {

})

사용 권한 수준이 다양한 경우 다음과 같이 구성할 수 있습니다.

const LEVELS = Object.freeze({
  basic: 1,
  pro: 2,
  admin: 3
});

/**
 *  Check if user has the required permission level
 */
module.exports = (role) => {
  return (req, res, next) => {
    if (LEVELS[req.user.role] < LEVELS[role]) return res.status(401).end();
    return next();
  }
}

2021년이니까 ES6 구문을 사용하면 어떨까요?... NodeJS v14.16.1을 사용하면 아래 예제가 매력적으로 작동합니다 :-)

고속 라우터 사용

const someFunc = ({ option1, option2 }) =>
 router.get("/", (req, res, next) => {
    
 // code
    
 next();
});

module.exports = someFunc;

또는

const someFunc = ({ option1, option2 }) =>
     (req, res, next) => {
        
     // code
        
     next();
    };
    
 module.exports = someFunc;

그런 다음 다음과 같이 부릅니다.

const someFunc = require('./middlewares/someFunc.js');
app.use(someFunc({option1: 'test', option2: false ));

여기에 있는 문서를 따르면 이 문제를 해결할 수 있었고, 이 미들웨어를 만들고 경로에 액세스할 수 있는 role_ids 배열을 전달했습니다.

exports.authorize = function (roles) {
  return function (req, res, next) {
    console.log(roles)
    if (roles?.includes(req.user.role_id)) {
      return next()
    } else {
      return res.status(403).send({
        error: "Not Authorized to access this route"
      })
    }
  }
}

그리고 이렇게 경로 파일에 호출했습니다.

myRouter.get("/", authorize([USER_ROLES.OPERATOR]), getSomething);

사용자 역할이 무엇인지 궁금하다면 열거형과 같습니다.

const USER_ROLES = Object.freeze({
  ADMIN: 1,
  HOST: 2,
  OPERATOR: 3,
  LOCKER_ADMIN: 4,
  MERCHANT: 5,
  CUSTOMER: 6,
  COURIER: 7,
  ECOMMERCE: 8
});

이것에 대한 저의 간단한 해결책이 있습니다.기본적으로 미들웨어에 인수를 전달할 수 없지만 래퍼 기능을 사용하면 이를 달성할 수 있습니다.

const restrictTo = (...roles) => {
   return (req, res, next) => {
    // roles are : ['admin', 'user'], role : req.user.role
   if (!roles.includes(req.user.role)) // I am taking role from req.user you can get it from model
      {
       return new Error('You dont have permission to delete the tour', 404)
      }
   next();
  }
};
Call it like ...

router.delete(restrictTo('admin', 'user'), handler);

언급URL : https://stackoverflow.com/questions/12737148/creating-a-expressjs-middleware-that-accepts-parameters

반응형