Skip to content

[Feat] Auth API 추가 - #19

Merged
kosy00 merged 9 commits into
developfrom
feat/18-auth-api
Jun 24, 2026
Merged

[Feat] Auth API 추가#19
kosy00 merged 9 commits into
developfrom
feat/18-auth-api

Conversation

@kosy00

@kosy00 kosy00 commented Jun 24, 2026

Copy link
Copy Markdown
Owner

관련 이슈

closes #18

구현 내용

  • 회원가입 / 로그인 / 토큰 재발급 / 로그아웃 API 구현
  • JWT Access Token + Refresh Token 발급
  • Refresh Token Redis 저장 및 RTR 전략 적용
  • SwaggerConfig 추가

변경 사항

  • AuthController 작성 (회원가입, 로그인, 재발급, 로그아웃)
  • SignupRequestDto 작성 + @Valid 검증 어노테이션
  • LoginRequestDto 작성
  • TokenResponseDto 작성
  • AuthService 작성
  • 회원가입 로직 (이메일 중복 체크, 비밀번호 암호화)
  • 로그인 로직 (이메일/비밀번호 검증, JWT 발급, Redis 저장)
  • 토큰 재발급 로직 (Refresh Token 검증 + RTR 전략)
  • 로그아웃 로직 (Redis Refresh Token 삭제)

체크리스트

  • 코드 구현 완료
  • 동작 확인
  • 불필요한 코드/주석 제거

Summary by CodeRabbit

Release Notes

  • New Features
    • 회원가입, 로그인, 로그아웃 기능 추가
    • 토큰 재발급(리프레시) 기능 추가
    • JWT 기반 인증 시스템 구현
  • Documentation
    • OpenAPI 기반 API 문서화 추가
  • Bug Fixes
    • 인증 필터 적용 범위를 세분화해 미허용 엔드포인트 처리 개선
  • Refactor
    • 데이터베이스 기본 키 생성 방식 변경
    • 사용자 엔티티 필드명 정규화

@kosy00 kosy00 self-assigned this Jun 24, 2026
@kosy00 kosy00 added the feat 새 기능 label Jun 24, 2026
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kosy00, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 13 minutes and 44 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e0d0624e-20d6-4719-88c8-12e5417cf7cc

📥 Commits

Reviewing files that changed from the base of the PR and between 8d172f5 and 32f7f43.

📒 Files selected for processing (1)
  • src/main/java/com/ilson/spotwork/common/exception/GlobalExceptionHandler.java
📝 Walkthrough

Walkthrough

User 엔티티의 ID 전략과 필드 구성이 바뀌고, Auth 요청·응답 DTO와 AuthService/AuthController가 추가되었습니다. SecurityConfigJwtAuthenticationFilter는 인증 예외 경로를 세분화했고, SwaggerConfig는 JWT 보안 스키마를 등록합니다.

Changes

JWT 기반 Auth API 구현

Layer / File(s) Summary
User 엔티티 수정 및 리포지토리 확장
common/entity/BaseEntity.java, domain/user/entity/User.java, domain/user/repository/UserRepository.java, domain/user/service/UserService.java
BaseEntity의 ID 생성 전략을 IDENTITY로 변경하고, User에 빌더/전체 인자 생성자를 추가하며 nickNamenickname으로 바꿉니다. UserRepositoryexistsByEmail, findByEmail 메서드를 추가하고 UserService 스켈레톤을 새로 만듭니다.
Auth 요청/응답 DTO 정의
domain/auth/dto/SignupRequestDto.java, domain/auth/dto/LoginRequestDto.java, domain/auth/dto/TokenResponseDto.java
회원가입 요청, 로그인 요청, 토큰 응답 DTO를 추가하고 각 필드에 validation 제약과 Lombok 접근자/빌더를 적용합니다.
AuthService 핵심 로직 구현
domain/auth/service/AuthService.java, infra/redis/RefreshTokenRepository.java
회원가입, 로그인, 토큰 재발급, 로그아웃 흐름을 구현하고, 리프레시 토큰 재발급용 원자적 비교 삭제 로직을 Redis 저장소에 추가합니다.
AuthController 엔드포인트 구성
domain/auth/controller/AuthController.java
/api/auth 아래에 signup, login, reissue, logout POST 엔드포인트를 추가하고, reissue의 Bearer 헤더 형식을 검증합니다.
SecurityConfig 및 JwtAuthenticationFilter 공개 경로 세분화
infra/security/SecurityConfig.java, infra/security/jwt/JwtAuthenticationFilter.java
인증 허용 경로를 3개 엔드포인트로 제한하고, JWT 필터가 동일 경로에서 실행되지 않도록 설정합니다.
SwaggerConfig JWT 보안 스키마 등록
common/config/SwaggerConfig.java
OpenAPI 문서에 JWT bearer 보안 스키마와 보안 요구사항, 메타데이터를 등록합니다.

Sequence Diagram(s)

sequenceDiagram
  participant Client as 클라이언트
  participant AuthController as AuthController
  participant AuthService as AuthService
  participant UserRepository as UserRepository
  participant JwtProvider as JwtProvider
  participant RefreshTokenRepository as RefreshTokenRepository

  Client->>AuthController: POST /api/auth/signup
  AuthController->>AuthService: signup(SignupRequestDto)
  AuthService->>UserRepository: existsByEmail(email)
  AuthService->>UserRepository: save(User)

  Client->>AuthController: POST /api/auth/login
  AuthController->>AuthService: login(LoginRequestDto)
  AuthService->>UserRepository: findByEmail(email)
  AuthService->>JwtProvider: generateAccessToken / generateRefreshToken
  AuthService->>RefreshTokenRepository: save(refreshToken)

  Client->>AuthController: POST /api/auth/reissue
  AuthController->>AuthService: reissue(refreshToken)
  AuthService->>JwtProvider: validateToken / extractUserId
  AuthService->>RefreshTokenRepository: compareAndDelete(userId, refreshToken)
  AuthService->>RefreshTokenRepository: save(newRefreshToken)

  Client->>AuthController: POST /api/auth/logout
  AuthController->>AuthService: logout(userId)
  AuthService->>RefreshTokenRepository: deleteByUserId
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • kosy00/ilson#13: BaseEntity의 ID 전략 변경과 User 엔티티 수정이 같은 엔티티 경로를 직접 공유합니다.
  • kosy00/ilson#14: SecurityConfig의 인증 허용 경로 설정이 이 PR의 변경과 동일한 보안 설정 축에 있습니다.
  • kosy00/ilson#15: JwtAuthenticationFilter의 경로 스킵 로직이 이 PR의 공개 Auth 경로 분리와 직접 연결됩니다.

Poem

🐰 토끼가 깡총, JWT를 들고 와요
가입하고 로그인하고, 토큰도 새로 빛나요
Redis에 살짝, 재발급은 또르르
Swagger 문서엔 bearerAuth 반짝반짝!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning BaseEntity의 ID 생성 전략 변경과 비어 있는 UserService 추가는 Auth API 요구사항과 직접 관련이 없습니다. Auth 기능과 무관한 변경은 분리하거나, 왜 필요한지 이슈 범위에 맞게 설명을 추가하세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 58.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 Auth API 추가라는 핵심 변경을 간결하게 잘 요약합니다.
Description check ✅ Passed 요구된 섹션(관련 이슈, 구현 내용, 변경 사항, 체크리스트)이 모두 포함되어 있습니다.
Linked Issues check ✅ Passed 회원가입, 로그인, 재발급, 로그아웃, JWT/Redis 연동, Swagger 구성까지 #18의 요구사항을 충족합니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/18-auth-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/main/java/com/ilson/spotwork/common/config/SwaggerConfig.java (1)

16-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

HTTP bearer 타입에서 불필요한 .name() 설정

20번째 줄의 .name("Authorization")은 HTTP bearer 타입의 SecurityScheme에서는 불필요합니다. OpenAPI 3 스펙에서 bearer 인증은 Authorization 헤더를 암묵적으로 사용하며, name 필드는 apiKey 타입의 SecurityScheme에서만 헤더/쿼리/쿠키 이름을 지정하는 데 사용됩니다.

♻️ 제안하는 수정사항
 SecurityScheme securityScheme = new SecurityScheme()
         .type(SecurityScheme.Type.HTTP)
         .scheme("bearer")
-        .bearerFormat("JWT")
-        .name("Authorization");
+        .bearerFormat("JWT");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/ilson/spotwork/common/config/SwaggerConfig.java` around
lines 16 - 20, The SecurityScheme configuration in the SwaggerConfig class
contains an unnecessary .name("Authorization") call on the securityScheme
object. For HTTP bearer type authentication, the Authorization header is used
implicitly per OpenAPI 3 specification, and the name field is only applicable
for apiKey type SecurityScheme. Remove the .name("Authorization") method call
from the SecurityScheme chain, keeping only type(), scheme(), and bearerFormat()
method calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/com/ilson/spotwork/domain/auth/service/AuthService.java`:
- Line 45: The log statements in AuthService class at both line 45 (in the
signup completion log) and line 71 are logging email addresses as plain text
PII, which creates a security and privacy risk. Replace the direct logging of
request.getEmail() in both the log.info calls with a masked or minimized version
of the email identifier, such as using only the domain portion, a hash, or a
different non-sensitive identifier, to protect personal information from
exposure in logs.
- Around line 87-102: The refresh token rotation logic in AuthService has a race
condition because token validation and storage are not atomic operations. The
current flow retrieves the stored token, compares it, and then saves the new
token as separate steps, allowing concurrent requests with the same refresh
token to both pass validation. Replace the separate find, equality check, and
save operations with a single atomic compare-and-set operation in the
refreshTokenRepository, such as implementing a rotateIfMatch method that
validates the provided refresh token equals the stored token and only then
atomically updates it to the new token. This ensures that only one concurrent
request can successfully rotate the token, preventing multiple valid tokens from
being issued simultaneously.
- Around line 32-44: There is a race condition where two concurrent requests can
both pass the existsByEmail check and then both attempt to save, causing the
database unique constraint on the email field to be violated and throw
DataIntegrityViolationException. Wrap the userRepository.save(user) call in a
try-catch block to catch DataIntegrityViolationException and throw
CustomException(ErrorCode.DUPLICATE_EMAIL) instead, ensuring the user receives a
clear and consistent error message regardless of whether the duplicate is caught
at the application level or database level.
- Around line 36-42: The User object creation in the AuthService class uses the
role value directly from the client request via request.getRole(), which creates
a security vulnerability allowing privilege escalation where users could
register with elevated roles like ADMIN. Replace the .role(request.getRole())
assignment in the User.builder() chain with a hardcoded default role value
(typically Role.USER or similar) to enforce the server-side permission and
prevent clients from specifying arbitrary roles during registration.

---

Nitpick comments:
In `@src/main/java/com/ilson/spotwork/common/config/SwaggerConfig.java`:
- Around line 16-20: The SecurityScheme configuration in the SwaggerConfig class
contains an unnecessary .name("Authorization") call on the securityScheme
object. For HTTP bearer type authentication, the Authorization header is used
implicitly per OpenAPI 3 specification, and the name field is only applicable
for apiKey type SecurityScheme. Remove the .name("Authorization") method call
from the SecurityScheme chain, keeping only type(), scheme(), and bearerFormat()
method calls.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 52a9e3af-0017-4148-a515-53c7406c2667

📥 Commits

Reviewing files that changed from the base of the PR and between 069111c and d26a996.

📒 Files selected for processing (12)
  • src/main/java/com/ilson/spotwork/common/config/SwaggerConfig.java
  • src/main/java/com/ilson/spotwork/common/entity/BaseEntity.java
  • src/main/java/com/ilson/spotwork/domain/auth/controller/AuthController.java
  • src/main/java/com/ilson/spotwork/domain/auth/dto/LoginRequestDto.java
  • src/main/java/com/ilson/spotwork/domain/auth/dto/SignupRequestDto.java
  • src/main/java/com/ilson/spotwork/domain/auth/dto/TokenResponseDto.java
  • src/main/java/com/ilson/spotwork/domain/auth/service/AuthService.java
  • src/main/java/com/ilson/spotwork/domain/user/entity/User.java
  • src/main/java/com/ilson/spotwork/domain/user/repository/UserRepository.java
  • src/main/java/com/ilson/spotwork/domain/user/service/UserService.java
  • src/main/java/com/ilson/spotwork/infra/security/SecurityConfig.java
  • src/main/java/com/ilson/spotwork/infra/security/jwt/JwtAuthenticationFilter.java

Comment thread src/main/java/com/ilson/spotwork/domain/auth/service/AuthService.java Outdated
Comment thread src/main/java/com/ilson/spotwork/domain/auth/service/AuthService.java Outdated
@kosy00
kosy00 merged commit 1169572 into develop Jun 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 새 기능

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] Auth API

1 participant