एक्सप्रेस मिडलवेयर: अनुमति देने के केवल व्यवस्थापक या मध्यस्थ के लिए उपयोग

वोट
0

मैं एक मार्ग केवल मॉडरेटर या व्यवस्थापक द्वारा सुलभ होना चाहता हूँ। मैं मार्ग पर सरणी के एक मिडलवेयर लागू करने की कोशिश। लेकिन, यह सिर्फ पहुँच अगर एक मध्यस्थ के लागू करने में विफल रहता इनकार करते हैं।
हां, तो कहते हैं कि मैं व्यवस्थापक हूँ या मॉडरेटर मैं करने के लिए उपयोग कर सकते हैं /store-detail
लेकिन यहाँ, अगर मैं व्यवस्थापक हूँ मैं इसे क्योंकि यह रूप में अच्छी तरह मॉडरेटर के लिए जाँच का उपयोग नहीं कर सकते हैं।
यहाँ _both middlewares adminऔर moderatorलागू किया जा रहा है।
मैं इसे लागू करना चाहते हैं adminया moderator
मैं सिर्फ उन में से एक लागू करने के लिए कैसे कर सकते हैं?
तो यह है कि केवल व्यवस्थापक या मॉडरेटर उसे तक पहुँच सकते हैं।
verifyमिडलवेयर जेडब्ल्यूटी टोकन को सत्यापित करने के लिए है।
रूटर

router.post('/store-detail', [verify, admin, moderator], async (req, res) => {
    //validate data
}}

middlewares

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

module.exports = async function (req, res, next) { 
    // 401 Unauthorized
    const user = await User.findOne({ where: { id : req.user.id}})
    if(user.role !== 'moderator') return res.status(403).send({error: { status:403, message:'Access denied.'}});
    next();
  }
const User = require('../models').User

module.exports = async function (req, res, next) { 
    // 401 Unauthorized
    const user = await User.findOne({ where: { id : req.user.id}})
    if(user.role !== 'admin') return res.status(403).send({error: { status:403, message:'Access denied.'}});
    next();
  }
09/10/2019 को 12:52
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


4 जवाब

वोट
1

Middlewares क्रमिक क्रियान्वित कर रहे हैं, इसलिए पहले मिडलवेयर कि पहुँच से इनकार करते हैं, एक त्रुटि भेजता है। मैं एक ही मिडलवेयर कि एक पैरामीटर को स्वीकार करता सुझाव देते हैं:

module.exports = function hasRole(roles) {
  return async function(req, res, next) {
    const user = await User.findOne({ where: { id: req.user.id } });
    if (!user || !roles.includes(user.role) {
      return res.status(403).send({error: { status:403, message:'Access denied.'}});
    }
    next();
  }
}

और इस तरह मिडलवेयर का उपयोग करें:

router.post('/store-detail', verify, hasRole(['admin', 'moderator']), async (req, res) => {})
09/10/2019 को 13:09
का स्रोत उपयोगकर्ता

वोट
0

एक जेडब्ल्यूटी आधारित समाधान: (लंबी पोस्ट के लिए खेद है, अगर यह unappropriate है, मैं हटा सकते हैं)

उपयोगकर्ताओं मार्ग (मार्गों / users.js) यहाँ मैं लॉगिन आपरेशन में एक Auth-टोकन वापस जाएँ।

const auth = require("../middleware/auth");
const hasRole = require("../middleware/hasRole");
const bcrypt = require("bcryptjs");
const { User } = require("../models/user");
const express = require("express");
const router = express.Router();

router.post("/register", async (req, res) => {
  const { name, email, password } = req.body;

  let user = await User.findOne({ email });
  if (user) return res.status(400).send("User already registered.");

  user = new User({ name, email, password });
  const salt = await bcrypt.genSalt(10);
  user.password = await bcrypt.hash(user.password, salt);
  await user.save();

  const token = user.generateAuthToken();
  res.header("auth-token", token).send({ name, email });
});

router.post("/login", async (req, res) => {
  const { email, password } = req.body;

  let user = await User.findOne({ email });

  if (!user) return res.status(400).send("Invalid email or password.");

  const validPassword = await bcrypt.compare(password, user.password);

  if (!validPassword) return res.status(400).send("Invalid email or password.");

  const token = user.generateAuthToken();

  res.send(token);
});

module.exports = router;

user.js (उपयोगकर्ता मॉडल) यहाँ मैं जेडब्ल्यूटी के लिए भूमिका की जानकारी जोड़ने जब यह हस्ताक्षर करने:

const jwt = require("jsonwebtoken");
const mongoose = require("mongoose");

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true,
    unique: true
  },
  password: {
    type: String,
    required: true
  },
  role: {
    type: String,
    default: "user"
  }
});

userSchema.methods.generateAuthToken = function() {
  const token = jwt.sign(
    { _id: this._id, role: this.role },
    process.env.JWT_PRIVATE_KEY
  );
  return token;
};

const User = mongoose.model("User", userSchema);

exports.User = User;

मिडलवेयर / auth.js यहाँ मैं उपयोगकर्ता को प्रमाणित है, और अनुरोध करने के लिए टोकन डीकोड जोड़ने इतना है कि हम अगले middlewares में उपयोग कर सकते हैं।

const jwt = require("jsonwebtoken");

module.exports = function(req, res, next) {
  const token = req.header("auth-token");
  if (!token) return res.status(401).send("Access denied. No token provided.");

  try {
    const decoded = jwt.verify(token, process.env.JWT_PRIVATE_KEY);
    req.user = decoded;
    next();
  } catch (ex) {
    res.status(400).send("Invalid token.");
  }
};

मिडलवेयर / hasRole.js यहाँ हम जाँच अगर user.role आवश्यक भूमिकाओं संतुष्ट करता है।

module.exports = function hasRole(roles) {
  return function(req, res, next) {
    if (!req.user.role || !roles.includes(req.user.role)) {
      return res.status(403).send("Access denied.");
    }

    next();
  };
};


अन्त में हम उन मार्ग के लिए निम्न पथ जोड़ने भूमिका प्राधिकरण परीक्षण करने के लिए सक्षम होने के लिए।

router.get("/me", [auth, hasRole(["admin", "moderator"])], async (req, res) => {
  const user = await User.findById(req.user._id).select("-password");
  res.send(user);
});

परीक्षा करना:

इस यूआरएल को पोस्ट के साथ निम्नलिखित के साथ 3 उपयोगकर्ताओं अलग बनाएं

http: // localhost: 3000 / API / उपयोगकर्ताओं / रजिस्टर

{
    "name": "admin",
    "email": "admin@so.com",
    "password" : "123456"
}

{
    "name": "moderator",
    "email": "moderator@so.com",
    "password" : "123456"
}

{
    "name": "user",
    "email": "user@so.com",
    "password" : "123456"
}

MongoDB में, उपयोगकर्ताओं को संग्रह में हम व्यवस्थापक उपयोगकर्ता, और उपयोगकर्ता मॉडरेटर के लिए मध्यस्थ के लिए व्यवस्थापक भूमिका संपत्ति अद्यतन करें।

डाकिया या इसी तरह के उपकरण हम व्यवस्थापक या मॉडरेटर क्रेडेंशियल्स के साथ लॉगिन का उपयोग करना।

जवाब में, हम प्रमाणीकरण टोकन मिलता है, हम GET अनुरोध में इस संरक्षित endpoint के लिए Auth-टोकन शीर्षक में इसका इस्तेमाल करते हैं।

http: // localhost: 3000 / API / उपयोगकर्ताओं को मुझे /

आप स्थिति कोड 200 मिल जाएगा।

इस बार हम सामान्य उपयोगकर्ता क्रेडेंशियल्स के साथ लॉगिन। जवाब में, हम प्रमाणीकरण टोकन प्रतिलिपि बनाएँ, और GET अनुरोध में इस संरक्षित endpoint के लिए Auth-टोकन शीर्षक में इसका इस्तेमाल करते हैं।

http: // localhost: 3000 / API / उपयोगकर्ताओं को मुझे /

आप मिल जाएगा स्थिति कोड 403 निषिद्ध।

09/10/2019 को 14:04
का स्रोत उपयोगकर्ता

वोट
0

अप्रासंगिक हिस्सा

देखने की प्रणाली वास्तुकला की दृष्टि से, यहाँ मैं क्या कर जाएगा।

  1. इसके बजाय मिडलवेयर हर अंदर नेटवर्क अनुरोध बनाने का, एक टोकन में उपयोगकर्ता पहुँच स्तर की दुकान (माना जेडब्ल्यूटी टोकन)।

  2. व्यवस्था करने के लिए पल उपयोगकर्ता लॉगिन, बैकएंड के लिए एक अनुरोध बनाने के लिए, बैकएंड अनुरोध विवरण (जो पहुँच स्तर पर विचार करना चाहिए) और टोकन में उपयोगकर्ता जानकारी एन्क्रिप्ट पुनर्प्राप्त करने के लिए db से कर देगा। आपका टोकन पहुंच का स्तर शामिल करना चाहिए।

  3. हर अनुरोध पर, आप हेडर में टोकन, de-तहखाने टोकन होगा, और पहुँच स्तरों के विवरण सेट (res.locals टोकन सेट के लिए आदर्श जगह होना चाहिए)।

   const verifyUser = async (req, res, next) => {
        const token = req.cookies.userId
        if(token) {
          try {
            const tokenVerficiation = await verifyToken(token)
            res.locals.userId = tokenVerficiation.userId
            next()
          } catch (error) {
            return res.status(401).send(`Invalid Access token`)
          }
        } else { 
         return res.status(401).send(`Not Authorized to view this.`)
        }
    }

प्रासंगिक हिस्सा

जब से तुम तय कर रहे हैं res.status(403).send({error: { status:403, message:'Access denied.'}});यह समझ में क्यों यह अगले मिडलवेयर पर नहीं चला जाएगा बनाता है।

के बाद से एक एपीआई के लिए कॉल कर सकते हैं आप *Probablyहेडर एक बार भेजने द्वारा सुझाव दिया गया है Jérémie एल एक एकल नई मिडलवेयर बनाने का सबसे अच्छा तरीका हो सकता है

module.exports = function hasRole(roles) {
  return async function(req, res, next) {
    const user = await User.findOne({ where: { id: req.user.id } });
    if (!user || !roles.includes(user.role) {
      return res.status(403).send({error: { status:403, message:'Access denied.'}});
    }
    next();
  }
}
09/10/2019 को 13:59
का स्रोत उपयोगकर्ता

वोट
0

एक नया कार्य जैसे बनाएं isAuthorizedकि तर्क को संभालने के लिए।

यदि आप कहते हैं [verify, admin, moderator]अलग से वे एक-दूसरे पर निर्भर नहीं कर रहे हैं।

मार्ग:

router.post('/store-detail', isAuthorized, async (req, res) => {
    //validate data
}}

function isAuthorized(req, res, next) {
  if (!verify(req)) 
    return next();
  if (!admin(req) && !moderator(req)) 
    return res.status(403).send({error: { status:403, message:'Access denied.'}});
}

मिडलवेयर:

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

module.exports = async function (req, res, next) { 
  // 401 Unauthorized
  const user = await User.findOne({ where: { id : req.user.id}})
  if(user.role === 'moderator') 
    return true;
  return false;
}

मुझे लगता है कि आप को संशोधित करने के लिए है verify(req), admin(req)और moderator(req)

09/10/2019 को 13:06
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more