Spring Boot : API 접속 건수 제한하기

By | 2025년 10월 23일
Table of Contents

Spring Boot : API 접속 건수 제한하기

DDOS 공격에 대비하기 위해, 일정 접속 건수 이상의 API 호출을 제한한다.

의존성 추가

dependencies {
    // ......
    implementation("com.bucket4j:bucket4j-core:8.6.0")
}

서비스

@Service
@RequiredArgsConstructor
public class RateLimitService {
    private final Map<String, Bucket> cache = new ConcurrentHashMap<>();

    public boolean allowRequest(String key) {
        Bucket bucket = cache.computeIfAbsent(key, k -> {
            // 아이피당 분당 20회 제한
            Bandwidth limit = Bandwidth.builder()
                    .capacity(20)
                    .refillIntervally(20, Duration.ofMinutes(1))
                    .build();

            return Bucket.builder()
                    .addLimit(limit)
                    .build();
        });

        return bucket.tryConsume(1);
    }
}

컨트롤러

    @PostMapping("/myApi")
    public ResponseEntity<?> myApi(@Valid @RequestBody MyApiRequest request, HttpServletRequest httpRequest) {
        String clientKey = getClientIpAddress(httpRequest);

        if (!rateLimitService.allowRequest("refresh:" + clientKey)) {
            throw new TooManyAccessException("너무 많은 요청입니다. 잠시 후 다시 시도해주세요.");
        }

        // ......
    }

    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
            return xForwardedFor.split(",")[0].trim();
        }

        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty()) {
            return xRealIp;
        }

        return request.getRemoteAddr();
    }

답글 남기기