Внедрить HttpContext в промежуточное ПО InversifyJS - PullRequest
0 голосов
/ 16 января 2019

У меня есть следующий контроллер.

@controller('/users')
class UsersController {
    @httpGet('/', authMiddleware({ role: 'ADMIN' }))
    public get() { ... }
}

Я реализовал пользовательский AuthenticationProvider, который возвращает принципала, содержащего сведения о текущем аутентифицированном пользователе, включая роли пользователя.

.... 
return new Principal({
  firstName: "John",
  lastName: "Smit",
  roles: ["ADMIN"]
});
...

Это все работает нормально, но мне интересно, как я могу получить принципал из authMiddleware, который используется вышеупомянутым GET-маршрутом.

Пока у меня есть отвратительный взлом, который использует внутренние компоненты InversifyJS.

function authMiddlewareFactory() {
  return (config: { role: string }) => {
     return (
         req: express.Request,
         res: express.Response,
         next: express.NextFunction
     ): void => {
         const httpContext: interfaces.HttpContext = 
         Reflect.getMetadata(
             "inversify-express-utils:httpcontext",
             req
         );
         const principal: interfaces.Principal = httpContext.user;
         if (!principal.isInRole(config.role)) {
             res.sendStatus(HttpStatus.UNAUTHORIZED);
             return;
         }
         next();
     };
   };
 }

Пользовательский поставщик аутентификации использует заголовок авторизации для аутентификации пользователя и возвращает принципала. Я не хочу делать эту работу снова в промежуточном программном обеспечении, я просто хочу получить принципал.

Этот хак работает, но мне было интересно, если кто-нибудь знает более чистый способ получения HttpContext в этом промежуточном программном обеспечении.

Я знаю, что вы можете получить доступ к HttpContext и, следовательно, к принципалу (пользователю), если вы выходите из BaseMiddleware, но тогда мне не ясно, как вы передаете ему конфигурацию (параметры), например, желаемую роль. Связан со следующей проблемой InversifyJS.

https://github.com/inversify/InversifyJS/issues/673

1 Ответ

0 голосов
/ 17 января 2019

Это не поддерживается, но я понимаю, зачем это нужно. Мы не можем передать httpContext промежуточному программному обеспечению в качестве аргумента, потому что мы хотим обеспечить совместимость стандартного промежуточного программного обеспечения Express. Это означает, что единственный вариант - сделать что-то похожее на то, что вы сделали, но в идеале мы должны инкапсулировать это с помощью некоторого помощника.

Нам нужно реализовать что-то вроде следующей getHttpContext функции:

import * as express from "express";
import { getHttpContext } from "inversify-express-utils";

function authMiddlewareFactory() {
  return (config: { role: string }) => {
     return (
         req: express.Request,
         res: express.Response,
         next: express.NextFunction
     ): void => {
         const httpContext = getHttpContext(req);
         const principal: interfaces.Principal = httpContext.user;
         if (!principal.isInRole(config.role)) {
             res.sendStatus(HttpStatus.UNAUTHORIZED);
             return;
         }
         next();
     };
   };
 }

Пока это не будет реализовано, я не вижу никаких проблем с вашей реализацией, кроме утечки информации внутренних переменных.

...