nestJS] guard에 service 주입
guard는 기본적으로 모듈에 등록을 히자 않게 때문에 Global로 선언된 모듈만 inject가 가능합니다.
gaurd 에서 request header를 통해 넘어온 token 값을 검증하고, 사용자 정보를 뽑기 위해서 jwtService
를 Inject(주입) 해야 하였습니다.
우선 사용하려는 서비스를 가진 모듈을 @Global()
로 선언합니다.
Global로 선언할 경우 다른 모듈에서 imports
없이 사용이 가능하게 됩니다.
@Global()
@Module({
imports: [
TypeOrmModule.forFeature([...]),
],
providers: [JwtService,],
exports: [JwtService],
})
export class JwtModule {}
global-modules 에 보면, Global 모듈은 가능하면 최소한으로 사용하는게 설계 디자인에 좋다고 합니다. 일반적으로는 imports에 외부 모듈을 선언해서 사용하는 것을 권장합니다.
이후 Guard에서는 아래와 같이 사용합니다.
@Injectable()
export class AuthGuard implements CanActivate {
logger: Logger = new Logger(AuthGuard.name);
// 참고된 stackoverflow와 같이 @Inject()를 사용하면 서비스에서 호출되는 다른 Service에서 오류 발생
constructor(private jwtService: JwtService) {}
async canActivate(context: ExecutionContext) {
// this.logger.debug('AuthGuard ::');
const req = context.switchToHttp().getRequest();
const token = req.headers.authorization
? req.headers.authorization.split('Bearer ')[1]
: '';
if (token === undefined) {
throw new HttpException(
{ status: HttpStatus.UNAUTHORIZED, error: 'Token Is Not Found.' },
HttpStatus.UNAUTHORIZED,
);
}
req.user = await this.jwtService.verify(token);
const user = req.user;
if (!user) {
return false;
}
this.logger.debug('AuthGuard ok ::');
return true;
}
}
특이점은 Inject service into guard in Nest.JS과 같이 @Inject()
를 사용하면 jwtService에서 inject는 다른 Service를 찾지 못하는 오류가 발생합니다.