본문 바로가기

공부기록용

Validation(클라이언트로부터 전달된 데이터 검증), @AuthenticationPrincipal

spring에서 Validation이 필요한 이유

웹 상에서 클라이언트로부터 전달되는 데이터를 신뢰할 수 없다.
물론 프론트엔드에서 검증을 하겠지만 만일의 사태를 방지하기 위해
null, 공백, 범위를 벗어난 숫자 등은 반드시 검증이 필요하다.
검증하지 않으면 데이터가 null인 경우, NullPointerException 발생 가능성 및
db 제약 조건 위반 등으로 이어질 수 있음.

spring은 jakarta.validation 기반의 Bean Validation을 지원한다.
DTO 클래스에 애너테이션만 붙여도 자동으로 유효성 검사를 수행할 수 있다.
ex. @NotNull(null 불가), @NotEmpty(null과 ""불가), @NotBlank(null, "", " "불가),
@Size(문자길이 측정), @Email(이메일 형식), @Pattern(정규표현식)

1. Build.gradle에 Validation 의존성 추가

// Validation  
implementation 'org.springframework.boot:spring-boot-starter-validation'


2. dto에 Bean Validation 규칙? 적용하기

   public class BoardCreateRequestDto {
   @NotBlank(message="제목 입력은 필수입니다.")
   private String title;
   
   @NotBlank(message="내용 입력은 필수입니다.")
   private String content;
   }

 

 

컨트롤러단에서 검증하고 싶은 dto 객체 앞에 @Validated 어노테이션 적용하기

→ dto에 작성한 Bean Validation 기능이 @Valid로 인해 작동된다.

   @RestController
   public class BoardController {
   public ResponseEntity<BoardCreateResponse> create(
   @Valid @RequestBody BoardCreateRequestDto dto
   ) { }
   }


@AuthenticationPrincipal
controller 계층에서 @AuthenticationPrincipal 어노테이션을 사용했을 때,
사용자 정보를 가져올 수 있는 이유?
인증(ex. 회원가입한 유저가 로그인을 통해 자신임을 인증하는 경우) 요청(ex. 로그인)이 들어온 경우,
UsernamePasswordAuthenticationFilter 또는 이 필터를 extends한 객체에서 인증관련 작업을 처리한다.
예를 들면 jwt 토큰 검증, id/password를 확인해서 Authentication 객체를 만들어서

SecurityContextHolder에 저장하는 작업을 한다.

Authentication authentication = new UsernamePasswordAuthenticationToken(customUserDetails, null, authorities);

SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);


controller 계층에서 @AuthenticationPricipal을 사용했을 때,
1. SecurityContextHolder에서 SecurityContext를 꺼내고,
2. SecurityContext에서 Authentication객체를 꺼내고,
3. Authentication에서 Principal객체를 꺼냄(Authentication.getPrincipal())
4. 그것을 @AuthenticationPrincipal 파라미터 타입(CustomUserDetails)으로 바인딩한다.
즉, @AuthenticationPrincipal은 SecurityContextHolder.getContext().getAuthentication().getPrincipal()
이라고 봐도 무방하다고 gpt가 알려줌.

반응형