Express авторизация промежуточного программного обеспечения; когда роли недостаточно - PullRequest
0 голосов
/ 16 марта 2020

Я работаю с Node и Express для обработки запросов. Аутентификация на основе JWT и авторизация на основе ролей.

Итак, каждый раз, когда я нахожу в сети статью или учебное пособие о Express функциях промежуточного программного обеспечения авторизации, примеры слишком тривиальны, поскольку охватывают только такие запросы, как:

GET / выход из системы -------------- (1)
GET / админ-панель -------------- (3) )

Используя заголовок авторизации, содержащий JWT, каждый из этих URL легко фильтруется путем простого вычисления идентификатора запрашивающего пользователя для проверки существования в БД и, при необходимости, их роли. Все это делается в функции, размещенной между URL-адресом и целевым ресурсом, следовательно, промежуточным программным обеспечением. Затем:

(1) доступен для любого прошедшего проверку пользователя.
(2) доступен для любого прошедшего проверку пользователя, который также является администратором

Теперь для таких URL-адресов, как приведенный ниже, дополнительно может потребоваться проверка:

PATCH / users /: id -------------- (3)
GET / users /: id --- ----------- (4)

, поскольку администратор может просматривать и изменять профиль любого пользователя, но не администратор также может просматривать и изменять свой собственный профиль, затем:

(3) и (4) доступны либо для аутентифицированного администратора, либо для самого запрашивающего пользователя, что можно проверить, сравнив идентификатор, извлеченный из токена, с параметром :id в запросе.

Пример:

//AuthorizationMiddleware.js

const Authentication = {
  async authenticate(req, res, next) {
    try {
      const token = authorizationHeader.split(" ")[1];
      if (!token) return res.status(400).send({ message: "Token was not provided" });

      const decoded = jwt.verify(token, SECRET);
      const userID = decoded.userID;

      const user = (await db.query("SELECT * FROM my_user WHERE id = $1", [userID])).rows[0];

      if (!user) {
        return res.status(400).send({ message: "Token provided is invalid" });
      }

      req.user = { id: userID, role_id: user.role_id };

      next();
    } catch (error) {    
      console.error(error.toString());
      return res.status(500).send('error');
    }
  },

  async authorizeAdmin(req, res, next) {
    const role_id = req.user.role_id;
    if (role_id) {
      if (role_id !== 1) {
        return res.status(401).send('insufficient privileges');
      }

      next();
      return;
    }
  }
};

export default Authentication;

И использование

//server.js

app.post("/api/v1/login", UserHandler.login);

app.post(
  "/api/v1/users/new",
  [AuthorizationMiddleware.authenticate, AuthorizationMiddleware.authorizeAdmin],
  UserHandler.create
);

НО, что происходит, когда недостаточно просто знать идентификатор и роль пользователя, что, если URL похож на:

PATCH / posts /: id -------------- (5)

запрашивается? где только владелец сообщения (определенный пользователь) может изменять его.

В этом случае в параметрах нет информации о запрашивающем пользователе (:id - это идентификатор сообщения), недостаточно знать, находятся ли они в БД, недостаточно знать, являются ли они администратором, нам нужно каким-то образом определить, связан ли идентификатор этого поста с с пользователем, который делает запрос, в БД.

Как это можно сделать в обработчике промежуточного программного обеспечения без потери его цель только обслуживать аутентификацию / авторизацию? без доступа к таблице сообщения, чтобы проверить владельца?

Надеюсь, я объяснил себе.

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...