웅글웅글: Nest 게시판 + 채팅 8. Request vs. Security Context, 인증된 사용자 정보 가져오기

메밀·2024년 3월 21일
0

웅글웅글: NestJS

목록 보기
8/9
post-thumbnail

1. Passport vs. Spring Security

인증 자체는 JwtStrategy 클래스를 작성하고,
컨트롤러 메서드에 @UseGuard(AuthGuard("jwt"))를 붙이면 완성이다.

그러나 이번 포스팅에서는 NestJS의 인증과 Spring Security의 인증에 대해서 좀 더 자세히 살펴볼 것이다.

  1. NestJS에서 인증된 사용자 정보는 어디에 저장되는가?
  2. 그 정보를 어떻게 사용할 수 있는가?

바쁘신 분들은 맨 아래 요약만 보시면 됩니다 😆

1) 플로우는 똑같아요

JwtStrategy의 validate 메소드에 토큰 인증 로직을 작성한다.
코드는 따로 옮겨적지 않을 것이다.

헤더에서 JWT 추출 후 디코딩은 JwtStrategy 클래스가 알아서 해주고,
토큰 만료 여부와 DB에 해당회원의 존재를 검사한 뒤,
user 객체를 리턴한다.

그럼 로그인 이후 인증은 끝이다.

그런데 리턴한 user 값은 어디에 있을까?

2) 인증된 사용자 정보는 어디로🧐?

- Spring Security의 경우

			// 정상 토큰이면 해당 토큰으로 Authentication을 가져와서 SecurityContext에 저장
            if (accessToken.validate()) {
                Authentication authentication = tokenProvider.getAuthentication(accessToken);

                SecurityContextHolder.getContext().setAuthentication(authentication);
            }

자바의 경우 Authentication 타입 객체를 만들어 Security Context에 저장한다.

- Passport의 경우

결론부터 말하자면 Passport는

JWT 토큰으로 사용자를 인증하고, 인증된 사용자 정보를 '요청 객체'에 저장한다❗️

3) 인증된 사용자 정보를 쓰고 싶다면?

Spring Boot를 사용해서 애플리케이션을 만들 때,
인증된 사용자 정보가 필요하다면 @AuthenticationPrincipal을 사용하기만 하면 된다.

만약 NestJS에서 @AuthenticationPrincipal(과 같은 것)을 쓰고 싶다면?

구현해야 한다 ⭐️

2. 인증된 사용자 정보 사용하기 💡

1) AuthUser: 커스텀 데코레이터

나의 경우 AuthUser라는 데코레이터를 만들었다.

import { createParamDecorator, ExecutionContext } from "@nestjs/common";

const AuthUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
    const request = context.switchToHttp().getRequest();
    return request.user;
  }
)

export default AuthUser

간단히 request에서 유저 정보를 꺼내오는 역할이다.
사용법은 @AuthenticationPrincipal과 같다.

  @Get()
  @UseGuards(AuthGuard("jwt"))
  getAllByUserId(@AuthUser() user): Promise<ChatRoomListDto[]> {
    return this.chatService.getAllByUserId(user);
  }

2) Passport와 Spring Security의 실행 시점

참고로 둘은 실행 시점도 다르다.

Spring Security가 DispatcherServlet보다 먼저 실행된다면,
Passport는 ApplicationInstance 이후, (대충 DispatcherServlet이랑 비슷한 놈이다) 컨트롤러 이전에 동작한다.
Spring의 Interceptor와 같은 시점에 동작한다고 보면 된다.

3. 정리

구분Spring SecurityPassport
동작 시점DispatcherServlet 이전Application Instance 이후, Controller 이전
Spring Interceptor와 같은 시점
사용자 정보 저장Security Context에 저장Request 객체에 저장
사용자 정보 사용하기구현된 어노테이션, 사용자 객체 있음없음. 만들어야함

0개의 댓글