POST /api/trips)를 구현했습니다.TripRequest (DTO): 클라이언트로부터 여행 생성에 필요한 데이터를 받기 위한 DTO로, @Valid를 통해 데이터 유효성을 검증합니다.TripService: TripRequest와 사용자 정보를 받아 Trip 엔터티를 생성하고 DB에 저장하는 핵심 비즈니스 로직을 담당합니다.TripController: API 엔드포인트를 외부에 노출하고, TripService를 호출하여 요청을 처리합니다.JwtAuthenticationFilter를 구현하여 Spring Security 파이프라인에 통합했습니다.Authorization: Bearer ...)를 담아 전송합니다.JwtAuthenticationFilter가 요청을 가로채 토큰을 추출합니다.JwtProvider.validateToken()을 통해 토큰의 유효성을 검증합니다.UsernamePasswordAuthenticationToken 객체를 생성합니다.Authentication 객체를 SecurityContextHolder에 저장하여, 해당 요청이 인증되었음을 명시합니다.SecurityConfig 설정addFilterBefore()를 사용하여 우리가 만든 JwtAuthenticationFilter가 Spring Security의 기본 인증 필터보다 먼저 동작하도록 설정했습니다.permitAll()로 인증 없이 접근 가능한 경로(로그인, 회원가입 등)를, authenticated()로 인증이 필요한 경로(/api/**)를 명시하여 API를 보호합니다.@AuthenticationPrincipal)SecurityContextHolder에서 직접 사용자 정보를 꺼내는 번거로움을 줄이고, 컨트롤러에서 인증된 사용자 정보를 파라미터로 바로 주입받도록 개선했습니다.
@AuthenticationPrincipal: 이 어노테이션을 사용하면 JwtAuthenticationFilter가 SecurityContextHolder에 저장한 사용자 정보를 컨트롤러 메서드에서 간편하게 조회할 수 있습니다. 이는 코드의 가독성과 테스트 용이성을 크게 향상시킵니다.
// TripController.java 예시
@PostMapping
public ApiResponse<Void> createTrip(
@Valid @RequestBody TripRequest request,
@AuthenticationPrincipal UserDetailsImpl userDetails // 바로 주입받아 사용
) {
tripService.createTrip(request, userDetails.getUsername());
return ApiResponse.ok("여행이 성공적으로 등록되었습니다.");
}