ID: key_26_22_05_25_P1_1_2 Created date: 5월 25 2026 월요일

연관 문서


개요

JWT 기반 인증/인가 시스템을 구현한다. 로그인, 회원가입, 토큰 갱신 API를 제공한다.


API 목록

MethodPath설명인증
POST/api/v1/auth/register회원가입불필요
POST/api/v1/auth/login로그인 (JWT 발급)불필요
POST/api/v1/auth/logout로그아웃 (토큰 무효화)필요
POST/api/v1/auth/refreshAccess Token 갱신Refresh Token
GET/api/v1/users/me내 프로필 조회필요
PUT/api/v1/users/me내 프로필 수정필요

Claude Code 작업 수행서

목표

JWT 기반 인증 API 전체를 구현한다. Access Token + Refresh Token 이중 토큰 전략을 사용한다.


작업 지시

CIRA 서버에 JWT 인증 API를 구현해줘. CLAUDE.md 컨벤션을 반드시 준수해.

[프로젝트 경로]
- C:\workspace\tsh\boilerplate\be\befw-lib-core\src\main\java\com\tsh\starter\befw\lib\core

[토큰 전략]
- Access Token: JWT, 만료 15분, Authorization 헤더 (Bearer)
- Refresh Token: Opaque 토큰 (UUID), 만료 7일, HttpOnly Cookie
- Refresh Token은 DB에 저장하지 않고 Redis에 저장 (없으면 임시로 DB users 테이블 컬럼 추가)

[수행 작업]

1. 의존성 추가 (maven)
   - spring-boot-starter-security
   - jjwt-api, jjwt-impl, jjwt-jackson (io.jsonwebtoken)
   - spring-boot-starter-data-redis (Refresh Token 저장)

2. 도메인 패키지 구성
   com.tsh.starter.befw.lib.core/
   ├── interfaces/rest/auth/AuthController.java
   ├── apService/auth/AuthService.java
   ├── apService/auth/JwtService.java
   ├── apService/auth//RefreshTokenService.java
   ├── apService/auth/dto/
   │   ├── LoginRequest.java       (email, password)
   │   ├── LoginResponse.java      (accessToken, tokenType, expiresIn)
   │   ├── RegisterRequest.java    (email, name, password)
   │   └── RefreshRequest.java
   └── config/security/
       ├── JwtAuthenticationFilter.java
       ├── SecurityConfig.java
       └── CustomUserDetailsService.java

   com.tsh.starter.befw.lib.core/
   ├── interfaces/rest/auth/UserController.java
   ├── apService/auth/UserService.java
   └── apService/auth/dto/
       ├── UserResponse.java
       └── UpdateProfileRequest.java

3. JwtService 구현
   - generateAccessToken(UserDetails): String
   - generateRefreshToken(): String
   - validateToken(String token): boolean
   - extractEmail(String token): String
   - 비밀키: application.yml jwt.secret (256-bit 이상)

4. SecurityConfig 구현
   - 허용 경로: POST /api/v1/auth/login, POST /api/v1/auth/register, POST /api/v1/auth/refresh
   - 나머지 전체 인증 필요
   - CORS 설정 (허용 Origin: NEXT_PUBLIC_URL)
   - CSRF 비활성화 (JWT 사용)
   - JwtAuthenticationFilter를 UsernamePasswordAuthenticationFilter 앞에 등록

5. 각 API 구현
   POST /auth/register:
   - 이메일 중복 체크
   - 비밀번호 BCrypt 해시
   - users 테이블 INSERT
   - 201 CREATED 반환

   POST /auth/login:
   - 이메일/비밀번호 검증
   - Access Token 생성
   - Refresh Token 생성 → Redis 저장 (key: refresh:{token}, value: userId, TTL: 7일)
   - Refresh Token → HttpOnly Cookie 설정
   - Access Token → 응답 body

   POST /auth/refresh:
   - Cookie에서 Refresh Token 추출
   - Redis에서 유효성 검증
   - 새 Access Token 발급
   - (선택) Refresh Token Rotation 구현

   POST /auth/logout:
   - Redis에서 Refresh Token 삭제
   - Cookie 만료 처리

6. 단위 테스트 작성
   - AuthService 로그인 성공/실패 테스트
   - JwtService 토큰 생성/검증 테스트
   - 통합 테스트: POST /auth/login → 200 + accessToken 필드 존재

[준수 사항]
- 비밀번호는 BCryptPasswordEncoder 사용 (강도 12)
- 에러 응답은 ErrorCode 사용 (AUTH_INVALID_CREDENTIALS, AUTH_TOKEN_EXPIRED 등)
- 모든 민감 정보는 application.yml placeholder 처리 (실제값 하드코딩 금지)

완료 기준

항목기준
회원가입 API201 반환, users 테이블 INSERT 확인
로그인 API200 + accessToken, Cookie에 refreshToken 설정
토큰 갱신만료된 Access Token → Refresh로 새 발급
인증 필터유효한 토큰으로 /users/me 200 반환
단위 테스트전체 통과

후행 작업