2026. 6. 25. 15:16ㆍ부트캠프/TIL(Today I Learned)
오늘 배운 내용
1. Spring Security + JWT 인증/인가 구조
기존에는 로그인 기능을 Controller → Service 에서 직접 처리했지만, Spring Security와 JWT를 사용하면 로그인 자체를 Security Filter Layer에서 처리한다는 점을 배웠다.
기존 로그인 방식
Client
↓
LoginController
↓
UserService
↓
DB 조회
↓
JWT 생성
↓
응답
JWT + Spring Security 방식
Client
↓
JwtAuthenticationFilter
↓
AuthenticationManager
↓
UserDetailsService
↓
DB 조회
↓
JWT 생성
↓
응답
특히 UsernamePasswordAuthenticationFilter를 상속받아 JwtAuthenticationFilter를 구현하고, 로그인 성공 시 JWT를 생성하여 쿠키에 저장하는 구조를 이해할 수 있었다.
또한 JwtAuthorizationFilter를 통해 매 요청마다 JWT를 검증하고 인증 정보를 SecurityContext에 저장하는 과정도 학습했다.
2. Spring Security 권한(Authorization) 관리
권한은 ROLE_ 접두사를 사용한다.
ROLE_USER
ROLE_ADMIN
UserDetailsImpl에서 권한 정보를 생성하고,
new SimpleGrantedAuthority("ROLE_ADMIN");
@Secured 애너테이션을 활용하여 특정 API 접근을 제한할 수 있다.
@Secured(UserRoleEnum.Authority.ADMIN)
@GetMapping("/products/secured")
또한
@EnableMethodSecurity(securedEnabled = true)
설정을 통해 @Secured 기능을 활성화할 수 있다는 점도 알게 되었다.
3. Bean Validation
사용자 입력값 검증을 위한 Bean Validation을 학습했다.
주요 애너테이션
@NotNull
@NotEmpty
@NotBlank
@Size
@Max
@Min
@Positive
@Negative
@Email
@Pattern
예시
@NotBlank
private String username;
@Email
private String email;
@Positive
private int price;
@Valid를 사용하면 DTO에 대한 검증이 자동으로 수행된다.
@PostMapping
public String signup(
@Valid SignupRequestDto requestDto,
BindingResult bindingResult
)
4. BindingResult
Validation 실패 시 발생하는 오류를 처리하기 위해 BindingResult를 사용한다.
if(bindingResult.hasErrors()) {
...
}
Validation 오류가 발생했을 때 예외를 발생시키는 대신 오류 정보를 저장해주기 때문에 개발자가 직접 예외 처리를 할 수 있다.
List<FieldError> errors =
bindingResult.getFieldErrors();
오류 필드명과 메시지를 확인할 수 있다.
5. RestTemplate
Spring에서 서버와 서버 간 통신(Server To Server)을 쉽게 처리하기 위한 기능이다.
예를 들어
우리 서버
↓
카카오 API
처럼 외부 API를 호출할 때 사용한다.
GET 요청
ResponseEntity<ItemDto> responseEntity =
restTemplate.getForEntity(uri, ItemDto.class);
JSON 응답을 DTO로 자동 변환해준다.
POST 요청
ResponseEntity<ItemDto> responseEntity =
restTemplate.postForEntity(
uri,
user,
ItemDto.class
);
POST 방식으로 요청을 보낼 수 있다.
Exchange 방식
가장 유연한 방식이다.
ResponseEntity<String> responseEntity =
restTemplate.exchange(
requestEntity,
String.class
);
Header, Body, Method를 모두 직접 설정할 수 있다.
RequestEntity<User> requestEntity =
RequestEntity.post(uri)
.header("X-Authorization", token)
.body(user);
실무에서는 인증 토큰이나 커스텀 헤더를 함께 보내야 하는 경우가 많기 때문에 자주 사용된다고 한다.
새롭게 알게 된 점
1. 로그인은 Controller가 아닌 Filter에서 처리할 수 있다.
지금까지는 로그인 기능을 Controller에서 처리하는 것이 당연하다고 생각했는데, Spring Security에서는 로그인 자체를 Filter가 처리한다는 점이 인상 깊었다.
특히 /login 요청이 Controller까지 도달하지 않고 Filter에서 바로 인증을 수행한다는 점을 처음 알게 되었다.
2. SecurityContext의 역할
JWT 검증 후 사용자 정보를 SecurityContext에 저장하면 이후 요청에서는 인증된 사용자로 인식된다는 점을 이해하게 되었다.
이를 통해
@AuthenticationPrincipal
로 현재 로그인한 사용자 정보를 쉽게 가져올 수 있다는 점도 알게 되었다.
3. Validation은 단순한 null 체크가 아니다.
Validation을 통해
- 문자열 길이 검증
- 이메일 형식 검증
- 숫자 범위 검증
- 정규식 검증
등 다양한 검증을 매우 쉽게 수행할 수 있다는 점을 배웠다.
4. RestTemplate의 자동 역직렬화
JSON 응답을 직접 파싱하지 않아도
ItemDto.class
만 지정하면 자동으로 DTO로 변환된다는 점이 매우 편리하다고 느꼈다.
내일 학습 목표
Spring 심화 강의 수강
회고
오늘은 Spring Security와 JWT의 전체 흐름을 조금 더 명확하게 이해할 수 있었던 날이었다.
특히 로그인 처리가 Controller가 아니라 Security Filter에서 이루어진다는 점이 가장 큰 수확이었다. 처음에는 필터의 동작 순서가 복잡하게 느껴졌지만, AuthenticationFilter → AuthenticationManager → UserDetailsService → DB 흐름을 여러 번 따라가며 이해할 수 있었다.
또한 Validation과 BindingResult를 학습하면서 사용자 입력값 검증의 중요성을 다시 한번 느꼈다. 단순히 기능이 동작하는 것보다 잘못된 입력을 안전하게 처리하는 것이 훨씬 중요하다는 점을 알게 되었다.
RestTemplate 실습도 진행하면서 서버 간 통신의 기본 구조를 익힐 수 있었고, 앞으로 외부 API를 연동할 때 어떤 방식으로 요청을 보내고 응답을 받아야 하는지 감을 잡을 수 있었다.
내일은 Spring 심화 강의를 수강하면서 JWT 인증 구조와 Security 흐름을 다시 정리하고, 실습 위주로 복습하여 개념을 확실하게 내 것으로 만드는 것을 목표로 한다.
'부트캠프 > TIL(Today I Learned)' 카테고리의 다른 글
| [내일배움캠프 사전캠프_단기심화_8기]_영속성 컨텍스트 및 그 외 TIL (0) | 2026.06.27 |
|---|---|
| [내일배움캠프_단기심화_8기]_Days-5-TIL (0) | 2026.06.26 |
| [내일배움캠프 사전캠프_단기심화_8기]_Day 3 TIL (0) | 2026.06.24 |
| [내일배움캠프 사전캠프_단기심화_8기]_Day 2 TIL (0) | 2026.06.23 |
| [내일배움캠프 사전캠프_단기심화_8기]_Day 1 오늘의 학습 키워드 (0) | 2026.06.22 |