API
작은 API에 rate limit을 넣기 전 응답 기준부터 정한 설정 노트
로그인과 문의 API에 제한을 추가하면서 상태 코드와 프록시 신뢰 범위를 정한 메모.
숫자보다 먼저 정한 기준
문의 폼 로그에 같은 IP의 POST가 짧은 시간에 수십 번 쌓였다. DB보다 이메일 알림이 먼저 묻혔다. 처음에는 분당 10회라는 숫자만 넣으려 했지만 로그인과 문의 API를 같은 정책으로 묶으면 정상 사용자를 막을 수 있었다.
엔드포인트를 나눴다
로그인은 짧고 엄격하게, 문의는 새로고침을 고려해 더 길게 잡았다. 메모리 저장소는 개발용이고 여러 서버에서는 Redis처럼 공유 저장소가 필요하다.
const policy = {
login: { limit: 5, windowMs: 60_000 },
contact: { limit: 3, windowMs: 600_000 },
};
제한 시에는 프론트가 구분할 수 있게 429와 재시도 시간을 보냈다.
return Response.json({ message: '잠시 후 다시 시도해 주세요.' }, {
status: 429, headers: { 'Retry-After': '60' }
});
프록시 헤더의 함정
로컬에서는 x-forwarded-for를 바로 읽어도 되지만, 공개 서버가 클라이언트 헤더를 그대로 받으면 IP를 위조할 수 있다. 내가 관리하는 Nginx가 덮어쓰는 경로에서만 신뢰한다.
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
적용 확인
- 연속 클릭에서 429와 안내가 보이는지 확인한다.
Retry-After를 응답한다.- 다중 인스턴스의 카운터를 공유한다.
- IP 로그는 필요한 범위만 마스킹한다.
rate limit은 끝이 아니라 알림과 비용을 지키는 첫 울타리다.