본문 바로가기

공부/TIL

23.11.22

오늘 정말 많은 기능들을 구현했다.

1. Spring Security를 이용한 인증

Spring Security를 이용해서 Jwt토큰 방식으로 사용자 인증을 하는 기능을 구현했다.

첫번째로 JwtUtil 클래스를 통해 Jwt를 다루는 클래스를 만들었다. JwtUtil클래스에는 JwtToken을 만들어 주는 기능, Jwt토큰을 확인하는 기능, 해당 토큰에서 정보를 담은 토큰을 잘라주는 기능, 잘라준 토큰에서 사용자 정보를 가져오는 기능, 토큰의 유효성을 판단하는 기능이 포함된다. Jwt토큰은 로그인 성공시 HttpServletResponse 클래스에 Header에 값을 넣어주는 방식으로 기능을 구현했다. 

두번째는 Filter를 설계했다. 필터는 인증이 필요한 요청일 때, 헤더에 들어있는 토큰이 유효한지를 판단하고, 유효하다면 유저의 정보를 반환 할 수 있도록 설계했다. 여기서의 과정이 조금 어렵지만 약간 패턴화 되었다고 생각해서 자주 반복 숙달 해야 된다 생각한다. 필터에서 유저의 값을 가져오는 흐름을 알아보자. 우선 우리는 헤더에 사용자 정보를 Claims에 넣어줬다. 그렇다면 유저의 정보를 담을 그릇은 UserDetails인터페이스를 구현한 구현체 UserDetailsImpl (커스텀)클래스다. 그리고 인증 정보를 담을 그릇은 SecurityContext. 우선 처음 빈 SecurityContext를 만들어준다음 UsernamePasswordAudthenticationToken클래스에서 인증 정보를 가져와서 Authentication 클래스의 객체에 담아준다.

그후 위에서 미리 만들어논 비어있는 SecurityContext에 인증값을 넣고, SecurityContextHolder에 인증값을 넣어주면 이제 

@AuthenticaationPrincipal 어노테이션을 달아주면 인증의 유효성을 판단할 수 있게된다! 이 흐름을 이해하는게 참 어려웠다..

이러면 다 끝났다.

	@DeleteMapping("/{commentId}")
	public ResponseEntity<CommonResponseDto> deleteComment(@PathVariable Long commentId, @AuthenticationPrincipal UserDetailsImpl userDetails) {
		try {
			commentService.deleteComment(commentId, userDetails.getUser());
			return ResponseEntity.ok().body(new CommonResponseDto("정상적으로 삭제 되었습니다.", HttpStatus.OK.value()));
		} catch (RejectedExecutionException | IllegalArgumentException ex) {
			return ResponseEntity.badRequest().body(new CommonResponseDto(ex.getMessage(), HttpStatus.BAD_REQUEST.value()));
		}
	}

간단히 댓글을 삭제하는 예시인데, 댓글을 삭제 하기 위해선 사용자 인증정보가 필요하다. 따라서 @AuthenticaationPrincipal 어노테이션을 UserDetailsImpl에 달아준다. 이러면? 유저정보의 인증 유효성을 판단해줌!!

 

정말 오랫동안 애먹엇던 Spring Security를 정복했다.

이 기능 구현을 하고 지금 게시글 CRUD에서 인증관련된 로직을 전부 짤 수 있었다. 게시글 게시/수정/삭제와 같은 권한이 필요한 경우 모드 사용자 인증을 마치고, 해당 작성자만 가능하도록 로직을 짤 수 있었다.

 

아! 여기서 우리는 Spring Security를 이용했지만, 세션방식이 아닌 Jwt방식을 사용했다. 세션방식에는 서버단에 검증 세션이 필요하다고 한다. 이는 곧 서버의 부하로 연결된다고 한다. Jwt방식은 위에서 말했듯, 헤더에 jwt값을 넣어서 줘야 한다. 따라서 통신데이터가 무거워 질 수 있다고 한다. 서로 장단이 있으니 상황에 맞춰서 써는게 좋겠다. 아직 세션 방식은 시도해보지 못했는데 나중에 여력이 되면 반드시 세션 방식을 통해 인증 방식또한 시도해봐야겠다.

 

오늘의 트러블 슈팅은 2개!(사실 자잘한거 더 많았는데 기록한 게 2개일뿐..)

https://taeho-fighting.tistory.com/61

 

스프링 내부 객체 사용 실수

인증/인가 필터단을 설계하면서 UserDetails를 구현한 UserDetailsImpl을 커스텀해서 사용했다. 이 UserDetailsImpl에 내가 사용하는 Entity인 User와 매칭 시키기 위해 UserRepository의 값을 꺼내와서 UserDetailsImpl

taeho-fighting.tistory.com

https://taeho-fighting.tistory.com/60

'공부 > TIL' 카테고리의 다른 글

23.11.24  (1) 2023.11.24
23.11.23  (1) 2023.11.23
23.11.21  (1) 2023.11.21
[팀프로젝트] 뉴스피드 API명세서  (1) 2023.11.21
23.11.20  (1) 2023.11.20