В nest.js возможно ли получить экземпляр службы внутри декоратора параметров? - PullRequest
2 голосов
/ 07 апреля 2019

Я хочу добиться чего-то подобного, используя nest.js: (что-то очень похожее на Spring Framework)

@Controller('/test')
class TestController {
  @Get()
  get(@Principal() principal: Principal) {

  }
}

После нескольких часов чтения документации я обнаружил, что nest.js поддерживает создание собственного декоратора. Поэтому я решил реализовать свой собственный @Principal декоратор. Декоратор отвечает за получение токена доступа из заголовка http и получение принципала пользователя из моей собственной службы аутентификации с использованием токена.

import { createParamDecorator } from '@nestjs/common';

export const Principal = createParamDecorator((data: string, req) => {
  const bearerToken = req.header.Authorization;
  // parse.. and call my authService..
  // how to call my authService here?
  return null;
});

Но проблема в том, что я понятия не имею, как получить свой экземпляр службы внутри обработчика декоратора. Является ли это возможным? И как? Заранее спасибо

1 Ответ

3 голосов
/ 07 апреля 2019

Невозможно внедрить сервис в ваш пользовательский декоратор.

Вместо этого вы можете создать AuthGuard, который имеет доступ к вашему сервису. Затем охранник может добавить свойство к объекту request, к которому затем можно получить доступ с помощью пользовательского декоратора:

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const bearerToken = req.header.Authorization;
    const user = await this.authService.authenticate(bearerToken);
    request.principal = user;
    // If you want to allow the request even if auth fails, always return true
    return !!user;
  }
}
import { createParamDecorator } from '@nestjs/common';

export const Principal = createParamDecorator((data: string, req) => {
  return req.principal;
});

и затем в вашем контроллере:

@Get()
@UseGuards(AuthGuard)
get(@Principal() principal: Principal) {
  // ...
}

Обратите внимание, что nest предлагает несколько стандартных модулей для аутентификации, см. документы .

...