-
nestjs에서 guard에 Global service Inject 처리NodeJS 2024. 6. 20. 17:18728x90
nestjs에서 guard에 Global service Inject 처리
guard에서 특정 Module의 서비스를 사용하고 있는 상화에서 해당 guard를 다른 Module에서 사용하려면 사용하려는 Module에서 해당 Service를 import 해야 합니다. 이를 Global 처리를 이용한 전략 스토어를 사용하는 예제 입니다.
Global Map 생성 및 전략 등록
// Global로 사용될 Map 생성 // https://github.com/lahuman/daily-quest/blob/main/api/src/auth/strategy-storage.ts export const StrategyStorage = new Map(); // https://github.com/lahuman/daily-quest/blob/main/api/src/auth/auth.strategy.ts import { Injectable } from '@nestjs/common'; import { UserService } from '../user/users.service'; import { StrategyStorage } from './strategy-storage'; import { UserTokenVo } from '../user/user-token.vo'; import { FirebaseService } from '../firebase/firebase.service'; import { UserVO } from '..//user/user.vo'; @Injectable() export class AuthStrategy { constructor( private userService: UserService, private firebaseService: FirebaseService, ) { // 초기 기동시 Global로 사용될 Map에 AuthStrategy.name로 해당 클래스 인스턴스 저장 StrategyStorage.set(AuthStrategy.name, this); } // 필요한 method 생성 fbVerify(token: string) { return this.firebaseService.authTokenVerify(token); } userVerify(token: string): UserVO { return this.userService.tokenValidate(token); } }
전략을 초기화 할 수 있도록 app.module에 선언
// https://github.com/lahuman/daily-quest/blob/main/api/src/app.module.ts import { Logger, Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { UsersModule } from './user/user.module'; import { FirebaseModule } from './firebase/firebase.module'; import { ConfigModule } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { SnakeNamingStrategy } from './core/snake-naming.strategy'; import { join } from 'path'; import { TodoModule } from './todo/todo.module'; import { AuthStrategy } from './auth/auth.strategy'; import { AllExceptionsFilter } from './core/exception.filter'; import { APP_FILTER } from '@nestjs/core'; // eslint-disable-next-line @typescript-eslint/no-var-requires require('./core/snake-naming.strategy').SnakeNamingStrategy; @Module({ imports: [ ConfigModule.forRoot({ envFilePath: ['.env.local', '.env'], isGlobal: true, }), TypeOrmModule.forRoot({ type: 'sqlite', namingStrategy: new SnakeNamingStrategy(), database: process.env.DB_SCHEMA, enableWAL: true, synchronize: false, entities: [join(__dirname, '**/*.entity.{ts,js}')], subscribers: [], logging: true, maxQueryExecutionTime: 1000, // 1초 이상되는 모든 쿼리 등록 extra: { synchronous: 'normal', temp_store: 'memory', mmap_size: 30000000000, page_size: 32768, }, }), UsersModule, TodoModule, FirebaseModule, ], controllers: [AppController], providers: [ AuthStrategy, // 제공할 AuthStrategy providers 처리 { // ExceptionFilter 등록 provide: APP_FILTER, useClass: AllExceptionsFilter, }, ], }) export class AppModule {}
guard 사용 예제
// https://github.com/lahuman/daily-quest/blob/main/api/src/user/user.guard.ts import { CanActivate, ExecutionContext, HttpException, HttpStatus, Injectable, Logger, } from '@nestjs/common'; import { StrategyStorage } from '../auth/strategy-storage'; import { AuthStrategy } from '../auth/auth.strategy'; @Injectable() export class UserGuard implements CanActivate { logger: Logger = new Logger(UserGuard.name); async canActivate(context: ExecutionContext) { const req = context.switchToHttp().getRequest(); const token = req.headers.authorization ? req.headers.authorization.split('Bearer ')[1] : ''; if (token === '' || token === undefined) { throw new HttpException( { status: HttpStatus.UNAUTHORIZED, error: 'Token Is Not Found.' }, HttpStatus.UNAUTHORIZED, ); } req.user = await StrategyStorage.get(AuthStrategy.name).userVerify(token); // 필요한 AuthStrategy.name의 서비스에서 호출 및 사용 const user = req.user; if (!user) { return false; } this.logger.debug('UserGuard ok ::'); return true; } }
Inject service into guard in Nest.JS를 보면 nestjs/passport 에서 영감을 얻은 내용이라고 합니다.
참고 자료
728x90'NodeJS' 카테고리의 다른 글
typescript에서의 class, interface 그리고 duck type (0) 2024.06.27 Typescript에서 특정 key를 가진 타입 생성 (0) 2024.06.25 [Nestjs TIP] whitelist 사용시 주의점! (0) 2024.06.18 [Nestjs TIP] Request Header에 validate 처리 (0) 2024.06.17 nestjs에서 registerAsync 사용시 isGlobal 설정 (0) 2024.06.12