RateLimiter 파사드의 구조
Laravel의 레이트 리밋은 Illuminate\Cache\RateLimiting\Limit 클래스와 RateLimiter 파사드로 구성되어 있습니다. 내부적으로는 캐시 드라이버(기본은 파일 또는 Redis)에 카운터를 보관하고, 요청 수를 추적합니다.
throttle 미들웨어가 받은 요청에 대해 RateLimiter::for()에서 정의한 클로저를 실행하고, 제한에 도달했다면 429 Too Many Requests를 반환합니다.
AppServiceProvider에서의 커스텀 리미터 정의
레이트 리밋의 설정은 App\Providers\AppServiceProvider의 boot() 메서드에서 합니다.
RateLimiter::for()의 제1인수는 리미터명으로, throttle 미들웨어에서 참조할 때 사용합니다. 제2인수의 클로저는 Illuminate\Cache\RateLimiting\Limit 인스턴스를 반환해야 합니다.
사용자별·IP 주소별·플랜별 레이트 리밋
인증된 사용자와 게스트로 제한을 다르게 함
사용자의 플랜에 따른 제한
IP 주소에 의한 글로벌 제한
특정 엔드포인트와 관계없이, IP 주소 단위로 스로틀링합니다.여러 제한을 조합함
배열로 반환하면, 모든 제한이 평가됩니다. 어느 하나에 도달한 시점에서429를 반환합니다.
같은
by 값을 갖는 여러 제한을 정의하는 경우에는, 키가 충돌하지 않도록 프리픽스를 붙여 주세요.throttle 미들웨어와 커스텀 리미터명의 지정
throttle 미들웨어에 정의한 리미터명을 전달합니다.
bootstrap/app.php에서의 등록
Laravel 11 이후, 미들웨어는 bootstrap/app.php에서 관리합니다.
API 라우트에의 적용 예
1
리미터를 정의한다
AppServiceProvider에 여러 리미터를 정의합니다.2
라우트에 미들웨어를 적용한다
응답 헤더(X-RateLimit-*)의 구조
throttle 미들웨어는 제한 정보를 응답 헤더에 자동 부여합니다.
커스텀 응답을 반환한다
RateLimiter::attempt()를 사용한 수동 체크
throttle 미들웨어를 사용하지 않고, 코드 안에서 임의의 타이밍에 레이트 리밋을 확인하고 싶은 경우에는 RateLimiter::attempt()를 사용합니다.
시도 횟수의 확인과 리셋
로그인 스로틀링의 예
응답 기반의 레이트 리밋
특정 응답만 카운트하고 싶은 경우에는after()를 사용합니다. 404 응답만 카운트함으로써 리소스 열거 공격을 방지하는 예:
Redis를 사용한 레이트 리밋
기본 캐시 드라이버를 Redis로 변경하는 것만으로,throttle 미들웨어도 자동적으로 Redis를 사용합니다.
Redis 드라이버의 설정
throttleWithRedis를 사용한다
Redis 전용의 최적화된 스로틀링 미들웨어를 사용하려면 bootstrap/app.php에서 throttleWithRedis()를 호출합니다.
throttle 미들웨어가 ThrottleRequestsWithRedis 클래스로 매핑되어, Redis의 아토믹 조작을 사용해 정확한 카운트가 이루어집니다.
Redis를 사용하는 이점
- 수평 스케일링 대응 — 여러 서버 인스턴스 간에서 카운터를 공유할 수 있음
- 고정밀도 — 아토믹 조작으로 레이스 컨디션을 방지
- TTL 관리 — Redis의 네이티브한 유효 기한 기능으로 카운터를 자동 삭제
관련 페이지
캐시
Redis를 포함한 Laravel의 캐시 드라이버의 설정과 사용법을 확인합니다.