Parametreleri kabul eden bir expressjs ara yazılımı oluşturma


106

Parametreleri kabul edebilen bir ara yazılım oluşturmaya çalışıyorum. Bu nasıl yapılabilir?

misal

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

})

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

   next();
}

42
Ha, benim tam senaryom için tam sorumu sordun, ama 6 yıl önce. SO harika.
— aero

6
@aero tam olarak aradığım şey: D
— Jeson Dias

4
@aero 7 yıl sonra aynısını arıyorum: D
— jean d'arme

4
@aero 7+ yıl sonra aynı şeyi arıyorum!
— 2019

4
@aero 8 ~ yıl sonra aynı şeyi arıyorum! \ o /
— Ítalo Sousa

Yanıtlar:


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

Aynı işlevin birden çok kopyasını yapmadığımdan da emin olmak istiyorum:

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

9
İkinci yöntem, istenen davranış olan veya olmayan parametreleri önbelleğe alır.
— Pier-Luc Gendreau

1
@Jonathan Ong, lütfen fonksiyonun ikinci tanımını açıklar mısınız? Orada neler oluyor? Aşağıdaki satırı anlamıyorum dönüş HasRole [role] || (HasRole [role] = function (req, res, next) {
— Rafay Hassan

1
@JonathanOng, düğümü o kadar iyi bilmeyenler için ikinci örneği biraz daha açıklar mısınız? (Ben dahil). Aynı işlevin birden çok kopyasını ne zaman alabilirsiniz ve bu ne zaman sorunlara neden olabilir? Teşekkürler.
— Dave

önbelleğe almadan app.get('/a', hasRole('admin'))ve app.get('/b', hasRole('admin'))her biri için yeni bir kapanış oluşturacaktır hasRole. Gerçekten büyük bir uygulamanız olmadıkça bunun gerçekçi bir önemi yoktur. ben sadece varsayılan olarak böyle kodluyorum.
— Jonathan Ong

14
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();
};

İyi ve basit fikir. Middleware gerçekten normal bir işlevdir. Neden ona başka değerler geçmiyor? Lütfen ilk işlevde req, res ve next'i ekleyin.
— zevero

1
Kod genellikle kendi adına konuşsa da, kodunuza bazı açıklamalar eklemek iyidir. Bu, yalnızca kod yanıtlarının eğiliminde olduğu için inceleme kuyruğunda belirdi.
— Will

SO'yu ziyaret etmeden önce bu yaklaşımı düşünüyordum ama "Elbette daha iyi bir yolu var" diye düşündüm. Ziyaret ettikten sonra bunun gerçekten en basit ve en etkili yol olduğunu görüyorum.
— Fusseldieb

3

Alternatif olarak, çok fazla vakanız yoksa veya rol bir dize DEĞİLSE:

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) {

})

zarif çözüm
— Leos Literak

2

Çeşitli izin seviyelerine sahipseniz, bunları şu şekilde yapılandırabilirsiniz:

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();
  }
}

0

Bu çözümü kullanıyorum. Vücut isteğinde bir jwt jetonu alıyorum ve oradan rol bilgileri alıyorum

//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 }

Bu nedenle, önce geçerli bir kullanıcı olup olmadığını öğrenmek için kimlik doğrulama ara yazılımını ve ardından kullanıcının api yoluna erişimi olup olmadığını bilmek için rol ara yazılımını kullanıyorum.

// router.js

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

Yararlı olmayı umuyorum

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.