1. 현재 문제점

지금 게시글 생성 요청을 보면:

{
    "title": "제목",
    "content": "내용",
    "author": "hong"
}

author를 클라이언트가 직접 입력합니다. 문제는:

로그인한 사용자: hong
요청에 보낸 author: "다른사람"
→ 다른 사람인 척 글을 쓸 수 있음

author는 클라이언트가 보내는 게 아니라, JWT 토큰에서 추출해야 합니다. 로그인한 사용자가 누구인지는 서버가 토큰으로 확인합니다.


2. SecurityContextHolder에서 사용자 정보 가져오기

JWT 필터가 인증에 성공하면 SecurityContextHolder에 Authentication을 저장합니다. 이걸 꺼내는 방법은 다음과 같습니다.

방법 1: SecurityContextHolder 직접 사용

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();    // JWT의 subject (username)

방법 2: @AuthenticationPrincipal 사용

Controller 파라미터에서 바로 꺼낼 수 있습니다:

@PostMapping
public ResponseEntity<...> create(
        @AuthenticationPrincipal String username,    // JWT의 subject
        @RequestBody PostCreateRequest request) {
}

하지만 우리의 JWT 필터에서 principal로 String(username)을 넣었기 때문에, String만 받을 수 있습니다. 더 풍부한 정보가 필요하면 커스텀 객체를 만들 수 있지만, 지금은 username만으로 충분합니다.

방법 3: 유틸 클래스로 추출 (권장)

여러 곳에서 현재 사용자를 가져와야 하므로, 유틸 클래스를 만듭니다:

package com.myname.board.security;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class SecurityUtil {

    private SecurityUtil() {}    // 인스턴스 생성 방지

    // 현재 로그인한 사용자의 username 반환
    public static String getCurrentUsername() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication == null || !authentication.isAuthenticated()) {
            throw new RuntimeException("인증 정보가 없습니다");
        }

        return authentication.getName();
    }

    // 현재 사용자의 역할 확인
    public static boolean hasRole(String role) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication == null) {
            return false;
        }

        return authentication.getAuthorities().stream()
                .anyMatch(auth -> auth.getAuthority().equals("ROLE_" + role));
    }
}

이제 어디서든 SecurityUtil.getCurrentUsername()으로 현재 로그인한 사용자를 가져올 수 있습니다.