왜 쓰는가 ?
- API 남용 방지(과도한 요청)
- 비즈니스 정책 반영(무료/유료 티어)
- 서버 자원 보호
- 보안 목적으로는 사용 X(IPsppofing 쉽게 가능함)
REST_FRAMEWORK = {
# 전역설정
'DEFAULT_THROTTLE_CLASSES' : [
'rest_framework.throttling.AnonRateThrottle', # 비인증
'rest_framework.throttling.UserRateThrottle',
]
# 설정 값
'DEFAULT_THROTTLE_RATES' : {
'anon': '100/day',
'user': '1000/day',
}
}
throttle_class
를 지정해 주면 된다.from rest_framework.throttling import UserRateThrottle
class MyView(APIView):
throttle_classes = [UserRateThrottle]
@api_view(['GET'])
@throttle_classes([UserRateThrottle])
def my_view(request):
...
클래스 | 설명 |
---|---|
AnonRateThrottle | 인증 안 된 사용자에게 IP 기준으로 제한 |
UserRateThrottle | 인증된 사용자 ID 기준 제한(없으면 IP로 fallback) |
ScopedRateThrottle | View 별로 throttle scope 설정해 제한 가능 |
CustomThrottle | 직접 throttle 로직 상성 가능(BaseThrottle 상속) |
X-Forwarded-For
: 10.0.0.1, 123.123.123.1REST_FRAMEWORK = {
'NUM_PROXIES': 2
# X-Forwarded-For: 123.123.123.1, 10.0.0.1, 10.0.0.2
# 앞에 1번째 = 실제 클라이언트 , 나머지 2개 NUM_PROXIES proxy ip 로 보는 것이다.
}
class BurstRateThrottle(UserRateThrottle):
scope = 'burst'
class SustainedRateThrottle(UserRateThrottle):
scope = 'sustained'
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'my_app.throttles.BurstRateThrottle',
'my_app.throttles.SustainedRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'burst: '60/min',
'sustained' : '1000/day',
}
}
# 이중 제한 적용
class myapp_view(APIView):
throttle_classes = [BurstRateThrottline, SustainedRateThrottle]
목적
"잠깐동안 급하게 많은 요청을 보내는 건 허용하되,
너무 오래 그렇게 보내지는 못 하게 하자"
비유
손님이 순간적으로 몰려드는건 괜챃지만,
계속 몰리면 주방이 터지는 거니까 그런 걸 막는 장치
목적
"서버 자원을 하루 단위로 적절히 분배해서 남용 방지"
비유
하루에 너무 많이 오는 단골손님을 쫓아낼 수는 없지만
일정 이상은 못 사게 제한하는 것
burst + sustained
Throttle
를 사용하는데 하나의 제한이 아닌 burst + sustained로 나눠서 두개의 제한을 둘수 있다.
또한 인증된 User와 그렇지 않은 유저의 제한을 나눌수 있다.
UserRateThrottle
-> 인증된 유저
AnonRateThrottle
-> 인증되지 않은 유저
각각을 상속받아 스코프를 나누어 제한을 나눌수도 있다.
API 프로젝트를 하다 Throttle에 대한 개념을 정리해 보았다.