[Stock101] @AuthenticationPrincipal을 활용한 유저 정보 관리

2026. 1. 31. 15:29·Archive(완료된 내용)/포트폴리오 강화

웹 애플리케이션을 개발할 때 "현재 로그인한 사용자의 ID"를 가져오는 작업은 필수적입니다. 하지만 매번 프론트엔드에서 ID를 파라미터로 받거나, 복잡한 시큐리티 로직을 컨트롤러에 적는 것은 보안과 생산성 측면에서 좋지 않습니다.

이 문제를 깔끔하게 해결해 주는 **@AuthenticationPrincipal**에 대해 알아보겠습니다.


1. 왜 @AuthenticationPrincipal인가?

❌ 기존 방식의 문제점 (ID를 파라미터로 받을 때)

  1. 보안 취약성: 사용자가 브라우저 개발자 도구에서 userId 파라미터를 조작하여 타인의 데이터를 조회/삭제하는 ID 변조 공격에 노출됩니다.
  2. 반복되는 검증: 서버는 파라미터로 온 ID가 진짜 로그인한 본인의 ID인지 확인하는 로직을 모든 API마다 작성해야 합니다.
  3. 지저분한 코드: 컨트롤러가 비즈니스 로직 외에 인증 정보를 파헤치는 코드들로 가득 차게 됩니다.

✅ @AuthenticationPrincipal의 장점

  1. 신뢰성: 프론트엔드가 보내주는 값이 아닌, 서버가 발행한 **암호화된 토큰(JWT)**에서 ID를 직접 꺼내오므로 조작이 불가능합니다.
  2. 간결함: 어노테이션 하나로 컨트롤러 파라미터에 사용자 정보를 즉시 주입받을 수 있습니다.
  3. 프론트엔드 편의성: 프론트엔드는 API 호출 시 userId를 일일이 챙길 필요 없이, HTTP 헤더에 토큰만 실어 보내면 됩니다.

2. JWT 환경에서의 동작 원리

JWT와 함께 사용할 때 전체적인 흐름은 다음과 같습니다.

  1. Request: 프론트엔드에서 HTTP Header에 JWT를 담아 요청을 보냅니다.
  2. Filter: JwtAuthenticationFilter가 토큰을 가로채서 유효성을 검사합니다.
  3. Extraction: 토큰 내부에 저장된 userId를 꺼냅니다.
  4. SecurityContext: 꺼낸 ID를 Authentication 객체에 담아 SecurityContextHolder에 저장합니다.
  5. Injection: 컨트롤러 실행 시 @AuthenticationPrincipal이 해당 값을 찾아 파라미터에 꽂아줍니다.

3. 실전 구현 단계 (Code-Level)

Step 1: JWT에 사용자 ID 포함하기 (Token 생성)

토큰을 만들 때 사용자 식별자(PK)를 Claim에 저장해야 합니다.

Java
 
public String createToken(Long userId, String email) {
    Claims claims = Jwts.claims().setSubject(email);
    claims.put("userId", userId); // 핵심: 토큰에 userId를 저장
    
    return Jwts.builder()
            .setClaims(claims)
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + validityInMilliseconds))
            .signWith(SignatureAlgorithm.HS256, secretKey)
            .compact();
}

Step 2: JWT 필터에서 Authentication 설정

토큰을 검증한 후, 컨트롤러에서 바로 꺼낼 수 있도록 인증 객체를 만들어 보관합니다.

Java
 
// JwtAuthenticationFilter 내부 로직 예시
if (token != null && jwtProvider.validateToken(token)) {
    Long userId = jwtProvider.getUserId(token); // 토큰에서 ID 추출
    
    // Principal 자리에 userId(Long)를 직접 넣거나, CustomUserDetails 객체를 생성해 넣습니다.
    Authentication auth = new UsernamePasswordAuthenticationToken(userId, null, authorities);
    SecurityContextHolder.getContext().setAuthentication(auth);
}

Step 3: 컨트롤러에서 주입받기

이제 모든 준비가 끝났습니다. 컨트롤러에서는 단 한 줄로 유저 ID를 얻습니다.

Java
 
@RestController
@RequestMapping("/api/notifications")
public class NotificationController {

    @GetMapping("/unread/count")
    public ResponseEntity<Integer> getCount(@AuthenticationPrincipal Long userId) {
        // userId는 시큐리티 필터가 토큰에서 꺼내준 신뢰할 수 있는 값입니다.
        return ResponseEntity.ok(notificationService.getUnreadCount(userId));
    }
}

4. 핵심 요약 및 주의사항

  • 용도 구분: "내 데이터"를 다룰 때는 @AuthenticationPrincipal을 사용하고, "검색 대상"이나 "다른 유저"를 지정할 때는 기존처럼 @PathVariable이나 @RequestParam을 사용하세요.
  • 타입 매칭: 필터에서 Authentication 객체를 만들 때 principal 자리에 넣은 데이터 타입(예: Long, String, UserDetails)과 컨트롤러에서 받는 파라미터 타입이 일치해야 합니다.
  • Null 체크: 로그인 권한이 필요 없는 API에서도 해당 어노테이션을 사용할 경우, 비로그인 시 null이 들어올 수 있으므로 적절한 처리가 필요합니다.

정리하자면, @AuthenticationPrincipal은 단순히 코드를 짧게 만드는 도구가 아니라, 서버 지향적인 인증 처리를 통해 보안을 강화하고 서버-클라이언트 간의 역할을 명확히 나누는 핵심 기술입니다.

저작자표시 비영리 변경금지 (새창열림)

'Archive(완료된 내용) > 포트폴리오 강화' 카테고리의 다른 글

[Stock101] 프로젝트 기획 마무리 정리 - 10일차  (0) 2026.02.03
[Stock101] 프로젝트를 정리하자.- 9일차  (0) 2026.02.01
[Stock101] 프론트를 재정비하자.- 8일차  (1) 2026.01.29
[stock101] 프론트앤드 구조를 잘 만들어야 관리가 쉽다.  (0) 2026.01.29
[Stock101] 반기 / 분기 공시 요약 및 전망 AI 기능 마무리- 8일차  (0) 2026.01.28
'Archive(완료된 내용)/포트폴리오 강화' 카테고리의 다른 글
  • [Stock101] 프로젝트 기획 마무리 정리 - 10일차
  • [Stock101] 프로젝트를 정리하자.- 9일차
  • [Stock101] 프론트를 재정비하자.- 8일차
  • [stock101] 프론트앤드 구조를 잘 만들어야 관리가 쉽다.
오늘은치킨이닭
오늘은치킨이닭
개발로 세상을 밝히자.(억지 맞음)
  • 오늘은치킨이닭
    개발세밝
    오늘은치킨이닭
  • 전체
    오늘
    어제
    • 분류 전체보기 (80)
      • Project(마감 기한이 정해진 목표) (2)
        • Docker(도커) (1)
        • Django(장고) (0)
        • 부트캠프 (1)
      • Archive(완료된 내용) (59)
        • 재취업준비 (8)
        • 포트폴리오 강화 (24)
        • 부트캠프 (3)
        • 팁 (2)
        • 데이터베이스 (2)
        • SQL (12)
        • 백엔드 (5)
        • 프론트엔드 (1)
        • 유니티(Unity) (2)
      • Area(일생동안 지속 유지하는 활동,마감X) (16)
        • 게임 (2)
        • 코딩테스트 (12)
        • 운영체제 (0)
        • DB (2)
      • Resource(지속적 관심을 갖는 주제분야) (1)
        • 애니메이션 (0)
        • 내가 선정한 맛집 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    롤 #룬 #자동적용 #블리츠 #다운로드 #도움 #TIP #브론즈 #아이언 #브실골 #아브실
    고클린 #cpu온도보는법 #cpu온도
    유니티 #설치 #방법 #다운
    명동교자
    DB #데이터베이스
    명동맛집
    명동
    맛집
    칼국수맛집
    인포그래픽 #자기소개서 #자기소개 #명함삭제
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
오늘은치킨이닭
[Stock101] @AuthenticationPrincipal을 활용한 유저 정보 관리
상단으로

티스토리툴바