전에 NestJS에서 Guard와 Strategy를 사용을 하려고 공부하다가
Guard가 어떤 방식으로 작동이 되는지 이해가 잘 안 되어서 코드분석을 했었는데
그 내용들을 정리한 내용입니다.
인증과 인가
- 인증(Authentication)
- 요청자가 자신이 누구인지 증명하는 과정
- 요청마다 jwt 토큰을 함께 보내 토큰으로 요청자가 라우터에 접근 가능한지 확인
- 보통 미들웨어로 구현
- 인가(Authorization)
- 인증을 통과한 유저가 요청한 기능을 사용할 권한이 있는지 판별
- 퍼미션(permission), 롤(role), ACL(Access Control List)와 같은 개념을 사용하여 유저가 가지고 있는 속성으로 사용을 허용할지 판별
- 보통 가드로 구현
💡 인가를 미들웨어가 아닌 가드로 구현하는 이유는 무엇일까 ?
미들웨어는 실행 콘텍스트에 접근하지 못하고,작업완료 후 next() 호출함으로 다음 어떤 핸들러가 실행되는지 알 수가 없습니다.
하지만 가드는 실행 컨텍스트 인스턴스에 접근할 수 있어 다음 실행될 작업을 알고 있기 때문입니다.
JwtGuard와 Strategy
Express 메서드로서의 미들웨어는 NestJS에도 존재하는데 즉, Express 미들웨어의 의미에서 일반적인 미들웨어가 아닙니다.
AuthGuard() #canActivate()는 적절한 PassportStrategy를 호출하게 됩니다.
이런 strategy은 특히 passport.use()가 호출되는 40-41행에 등록됩니다.
이것은 Passport.verify()에 사용할 passport strategy 클래스의 validate 메서드를 등록합니다.
💡 내부 논리의 대부분은 추상적이고 읽는 동안 콘텍스트가 손실될 수 있으므로 시간을 들여 클래스, 믹스인(mixins : 클래스를 반환하는 함수) 및 상속의 개념을 공부하는 것을 추천드립니다. (mixins에 대한 스터디 필요)
AuthGuard의 51행은 원래 passportFn이 생성된 곳이며 이 PassportFn에서는 passport.authenticate가 호출됩니다. (passport.verify을 호출)
(Passport의 코드를 읽는 것은 훨씬 더 혼란스럽기 때문에 원할 때 실행할 수 있습니다.)
canActivate() 메서드에 몇 가지 논리를 추가하려면 super.canActivate(context)를 호출하여 원래의 canActivate() 메서드를 호출할 수 있습니다. 결국 Passport.authenticate()를 호출하여 <Strategy>#validate를 호출할 수 있습니다.
@Injectable()
export class CustomAuthGuard extends AuthGuard('jwt') {
async canActivate(context: ExecutionContext): Promise<boolean> {
// custom logic can go here
const parentCanActivate = (await super.canActivate(context)) as boolean; // this is necessary due to possibly returning `boolean | Promise<boolean> | Observable<boolean>
// custom logic goes here too
return parentCanActivate && customCondition;
}
}
참고문헌
https://stackoverflow.com/questions/65557077/passportjs-nestjs-canactivate-method-of-authguardjwt
https://docs.nestjs.kr/guards#guards
'Backend > Nestjs' 카테고리의 다른 글
[NestJS] NestJS 란? (0) | 2022.06.10 |
---|---|
[NestJS] E2E Testing (0) | 2022.02.27 |
[NestJS] Swagger 생성하기 (0) | 2022.02.21 |
[NestJS] 유닛 테스트(Unit Testing) (0) | 2022.02.16 |
[NestJS] Docker 304 undefined 에러 (0) | 2022.02.14 |