एक एक्सप्रेसवे मिडलवेयर बनाना जो मापदंडों को स्वीकार करता है


106

मैं एक मिडलवेयर बनाने की कोशिश कर रहा हूं जो मापदंडों को स्वीकार कर सकता है। यह कैसे किया जा सकता है?

उदाहरण

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

})

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

   next();
}

42
हा, आपने मेरे सटीक परिदृश्य के लिए मेरा सटीक सवाल पूछा है, लेकिन 6 साल पहले। एसओ कमाल का है।
हवाई

6
@aero ठीक वही चीज जिसकी मुझे तलाश थी: D
जेसन डायस

4
@aero 7 साल बाद मैं उसी सटीक की तलाश कर रहा हूं: D
jean d'arme

4
@aero 7+ साल बाद मैं ठीक उसी चीज़ की तलाश में हूँ!
सिड

4
@aero 8 ~ साल बाद मैं ठीक उसी चीज की तलाश में हूं! \ o /
Stalo Sousa

जवाबों:


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

9
दूसरा तरीका मापदंडों को कैश करता है, जो वांछित व्यवहार नहीं हो सकता है।
पियर-ल्यूक गेंड्रेउ

1
@ जोनाथन ओंग, क्या आप फ़ंक्शन की दूसरी परिभाषा बता सकते हैं। वहाँ क्या हो रहा है? मैं निम्नलिखित लाइन हसरोल [भूमिका] को नहीं समझता हूँ || (हसरोल [भूमिका] = फंक्शन (पुनः, रेस, अगला) {
रफय हसन

1
@JonathanOng क्या आप कृपया दूसरे उदाहरण की व्याख्या कर सकते हैं जो नोड के बारे में नहीं जानते हैं? (मुझे शामिल करते हुए)। आप एक ही फ़ंक्शन की कई प्रतियां कब प्राप्त कर सकते हैं और कब यह समस्याएं पैदा कर सकता है? धन्यवाद।
डेव

कैशिंग के बिना, app.get('/a', hasRole('admin'))और app.get('/b', hasRole('admin'))प्रत्येक के लिए एक नया बंद होगा hasRole। जब तक आपके पास वास्तव में एक बड़ा अनुप्रयोग नहीं है, यह बहुत अधिक वास्तविक रूप से मायने नहीं रखता है। मैं सिर्फ डिफ़ॉल्ट रूप से इस तरह कोड।
जोनाथन ओंग

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

अच्छा और सरल विचार। मिडलवेयर वास्तव में सिर्फ एक सामान्य कार्य है। इसके लिए अन्य मान क्यों नहीं पास करते। पहले फ़ंक्शन में कृपया रीक, रेस और अगला शामिल करें।
ज्वेरो २०'१६ को .:३

1
जबकि कोड अक्सर खुद के लिए बोलता है, अपने कोड में कुछ स्पष्टीकरण जोड़ना अच्छा है। यह समीक्षा कतार में पॉप अप हुआ, क्योंकि कोड-ओनली उत्तर हैं।
विल

मैं SO पर जाने से पहले उस दृष्टिकोण के बारे में सोच रहा था, लेकिन मुझे लगा कि "मेह, निश्चित रूप से एक बेहतर तरीका है"। दौरा करने के बाद मैं देखता हूं कि यह वास्तव में सबसे सरल, सबसे प्रभावी तरीका है।
फसेलडिएब

3

वैकल्पिक रूप से यदि आपके पास बहुत अधिक मामले नहीं हैं या यदि भूमिका एक स्ट्रिंग नहीं है:

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

})

सुरुचिपूर्ण समाधान
Leos लीटरक

2

यदि आपके पास विभिन्न अनुमति स्तर हैं, तो आप उन्हें इस तरह से संरचना कर सकते हैं:

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

मैं इस समाधान का उपयोग करता हूं। मैं बॉडी रीक में 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 }

इसलिए पहले मैं यह जानने के लिए कि क्या कोई मान्य उपयोगकर्ता है, और तब उपयोगकर्ता को एप्री मार्ग तक पहुंच है या नहीं, यह जानने के लिए भूमिका मिडलवेयर का उपयोग करें।

// router.js

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

मुझे उपयोगी होने की उम्मीद है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.