Skip to content

Feat: 로그인·토큰 재발급 엔드포인트 Rate Limit 추가 - #254

Merged
jjh75607 merged 5 commits into
devfrom
feat/#246
May 31, 2026
Merged

Feat: 로그인·토큰 재발급 엔드포인트 Rate Limit 추가#254
jjh75607 merged 5 commits into
devfrom
feat/#246

Conversation

@jjh75607

@jjh75607 jjh75607 commented May 31, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 로그인 및 토큰 재발급 요청에 대한 레이트 리미팅 기능을 추가했습니다.
    • 클라이언트 IP별로 60초당 최대 10회 요청으로 제한하며, 초과 시 요청이 거부됩니다.
  • Tests

    • 레이트 리미팅 동작을 검증하는 단위 테스트를 추가했습니다.

jjh75607 and others added 3 commits May 31, 2026 18:36
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jjh75607 jjh75607 self-assigned this May 31, 2026
@jjh75607 jjh75607 added the Feat label May 31, 2026
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

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

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ 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.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f3862674-b24f-4c40-86cf-cc428ddc2f0d

📥 Commits

Reviewing files that changed from the base of the PR and between 147fb0f and 36170be.

📒 Files selected for processing (3)
  • src/main/java/soon/fridgely/global/security/ratelimit/LoginRateLimitAspect.java
  • src/main/resources/application.yml
  • src/test/java/soon/fridgely/global/security/ratelimit/LoginRateLimitAspectUnitTest.java
📝 Walkthrough

개요

로그인 및 토큰 재발급 요청에 대한 Redis 기반 IP별 레이트 리미팅을 구현하였습니다. 새로운 @LoginRateLimit 어노테이션, AOP Aspect, 예외 타입과 포괄적인 테스트를 추가했습니다.

변경사항

로그인 레이트 리미팅

레이어 / 파일 설명
레이트 리미팅 계약 정의
src/main/java/soon/fridgely/global/security/ratelimit/LoginRateLimit.java, src/main/java/soon/fridgely/global/support/exception/ErrorType.java
메서드 수준의 @LoginRateLimit 마커 어노테이션과 한도 초과 시 HTTP 429 응답을 위한 LOGIN_RATE_LIMIT_EXCEEDED 예외 타입을 정의합니다.
Redis 기반 Aspect 구현
src/main/java/soon/fridgely/global/security/ratelimit/LoginRateLimitAspect.java
요청 클라이언트 IP를 X-Forwarded-ForX-Real-IPremoteAddr 순으로 추출하고, Redis 키 login:ratelimit:{ip}의 카운트를 증가시킵니다. TTL이 없으면 60초로 설정하고, 10회 초과 시 경고 로그를 기록하고 예외를 발생시킵니다.
AuthController에 적용
src/main/java/soon/fridgely/domain/auth/controller/AuthController.java
/login/reissue 엔드포인트 메서드에 @LoginRateLimit 어노테이션을 추가하여 레이트 리미팅을 활성화합니다.
기능 검증 테스트
src/test/java/soon/fridgely/global/security/ratelimit/LoginRateLimitAspectUnitTest.java
Redis 조회/증가, TTL 관리, IP 추출 우선순위, 한도 초과 예외 발생을 검증하는 9가지 unit test를 작성합니다.

추정 코드 리뷰 노력

🎯 3 (보통 난이도) | ⏱️ ~20분

관련 이슈

관련 PR

  • Fridgely/Back-End#204: 동일한 /login/reissue 엔드포인트의 레이트 리미팅 메커니즘을 변경하는 PR (이전에는 Java 기반 RateLimitGuard 확인을 제거하고 Nginx 레이트 리미팅으로 전환)

로그인 요청 들어오면 🐰
Redis 카운트 재빠르게 🚀
IP별로 체크하고
열 번 넘으면 거절하지 ✋
보안 튼튼하게 지킨다~ 🔐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 로그인·토큰 재발급 엔드포인트에 Rate Limit을 추가하는 주요 변경사항을 명확하게 요약하고 있습니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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/#246

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 and usage tips.

@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: 3

🤖 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/soon/fridgely/global/security/ratelimit/LoginRateLimitAspect.java`:
- Around line 51-58: The current logic in LoginRateLimitAspect that trusts
request.getHeader("X-Forwarded-For") and request.getHeader("X-Real-IP") is
unsafe; change it so headers are only used when the request originates from a
trusted proxy (validate the incoming request.getRemoteAddr() against a
configured trustedProxy list) and otherwise fall back to
request.getRemoteAddr(); update the IP-extraction logic in the method that reads
headers (the code handling "X-Forwarded-For" and "X-Real-IP") to perform this
trusted-proxy check before splitting/returning header values and ensure a secure
default uses request.getRemoteAddr().

In
`@src/test/java/soon/fridgely/global/security/ratelimit/LoginRateLimitAspectUnitTest.java`:
- Around line 61-73: The test TTL이_없는_키는_expire를_설정한다 currently asserts expire
was called with any Duration, which won't catch regressions to the 60s window;
change the assertion to verify stringRedisTemplate.expire was called with the
exact Duration.ofSeconds(60) (or the constant used by LoginRateLimitAspect) for
the key "login:ratelimit:192.168.1.1" so the test fails if the TTL value
changes.
- Around line 103-140: The tests only assert no exception from
aspect.checkRateLimit() but don’t verify the actual Redis keys used; modify each
test (e.g., XForwardedFor_헤더의_첫번째_IP를_Rate_Limit_키로_사용한다,
XRealIP_헤더가_있으면_해당_IP를_Rate_Limit_키로_사용한다,
헤더가_없으면_remoteAddr를_Rate_Limit_키로_사용한다) to also verify the interactions: after
calling aspect.checkRateLimit() use Mockito.verify to assert
valueOperations.increment("login:ratelimit:<expected-ip>") was called and
Mockito.verify(stringRedisTemplate).getExpire("login:ratelimit:<expected-ip>")
(and optionally verifyNoMoreInteractions/valueOperations or
verifyNoMoreInteractions(stringRedisTemplate)) so the tests fail if a different
key is used.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fa611a15-1675-4cd2-8309-6894c0281f74

📥 Commits

Reviewing files that changed from the base of the PR and between 1026dd3 and 147fb0f.

📒 Files selected for processing (5)
  • src/main/java/soon/fridgely/domain/auth/controller/AuthController.java
  • src/main/java/soon/fridgely/global/security/ratelimit/LoginRateLimit.java
  • src/main/java/soon/fridgely/global/security/ratelimit/LoginRateLimitAspect.java
  • src/main/java/soon/fridgely/global/support/exception/ErrorType.java
  • src/test/java/soon/fridgely/global/security/ratelimit/LoginRateLimitAspectUnitTest.java

jjh75607 and others added 2 commits May 31, 2026 18:57
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jjh75607
jjh75607 merged commit 64fd785 into dev May 31, 2026
2 checks passed
@jjh75607
jjh75607 deleted the feat/#246 branch May 31, 2026 10:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat: 로그인·토큰 재발급 엔드포인트 Rate Limit 추가

1 participant