Когда использовать охрану и когда использовать промежуточное ПО в NestJs - PullRequest
1 голос
/ 02 октября 2019

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

Разделив это, я надеялся получитьчистое разделение. Сначала мое промежуточное программное обеспечение

@Injectable()
export class TokenMiddleware implements NestMiddleware {
  use(req: any, res: Response, next: NextFunction) {
    try {
      const headers: IncomingHttpHeaders = req.headers;
      const authorization: string = headers.authorization;
      const bearerToken: string[] = authorization.split(' ');
      const token: string = bearerToken[1];

      // !! Check if token was invalidated !!

      req.token = token;
      req.tokenPayload = verifyToken(token);
      next();
    } catch (error) {
      throw new UnauthorizedException();
    }
  }
}

Он только проверяет токен и расширяет объект запроса зашифрованным токеном и его полезной нагрузкой. Моя проверка подлинности

@Injectable()
export class AuthenticationGuard implements CanActivate {
  constructor(private readonly usersService: UsersService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request: any = context.switchToHttp().getRequest();

    try {
      const user: any = request.tokenPayload;

      if (!user) {
        throw new Error();
      }

      const findByIdDTO: FindByIdDTO = { id: user.id };
      const existingUser: UserRO = await this.usersService.findById(findByIdDTO);

      if (!existingUser) {
        throw new Error();
      }

      // attach the user to the request object?

      return true;
    } catch (error) {
      throw new UnauthorizedException();
    }
  }
}

Эта проверка проверяет, является ли предоставленный пользователь в загрузке токена допустимым. Если все хорошо, где я должен прикрепить пользователя к объекту запроса? Насколько я знаю, охранник только проверяет, правильно ли что-то. Но я не хочу хранить всю эту логику в промежуточном программном обеспечении токена. Где я могу прикрепить пользователя базы данных к запросу после завершения проверки в auth guard?

Ответы [ 2 ]

1 голос
/ 02 октября 2019

Если вы хотите сделать что-то похожее на Passport, вы всегда можете присоединить пользователя к req.user, что считается довольно стандартным тоном в мире Node.JS.

Дополнительный вопрос для вас: есть ли причина не иметь двух охранников, которые работают сразу за другим? Имейте одного охранника для проверки того, что токен существует и действительно является действительным токеном, и один для проверки пользователя на токене, действительно, является действительным. Таким образом, вы не используете промежуточное программное обеспечение (которое в основном включено для совместимости) и по-прежнему используете отдельную логику.

0 голосов
/ 03 октября 2019

Where can I attach the database user to the request after finishing the validation in the auth guard?

Я считаю, что Guard, как вы заметили, должен проверить, если данный пользователь имеет право использовать данный метод.

В зависимости от ваших потребностей, вы можете перейти к различнымпути:

1) использовать паспорт и стратегию, чтобы делать то, что вам нужно (https://stackoverflow.com/a/57929429/4319037 Я уже написал несколько слов и строк об этом). Более того, он уже охватит большую часть кода, необходимого для извлечения токена.

@Injectable()
export class HttpStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super()
  }

  async validate(token: string) {
    const user = await this.authService.findUserByToken(token);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

2) используйте Interceptor на уровне контроллера / метода, чтобы присоединить пользователя к данному запросу (и бросить, если токенотсутствует);ваша охрана уже получит user, поэтому вы можете проверить, есть ли у пользователя правильная роль / права для выполнения метода.

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

...