对匿名用户采用 IP 控制访问频率,对登录用户采用 用户名 控制访问频率。
from rest_framework.throttling import SimpleRateThrottle class VisitThrottle(SimpleRateThrottle):
"""匿名用户访问频率限制"""
scope = "AnonymousUser" # 随便写的,可以作为key保存在缓存中 def get_cache_key(self, request, view):
return self.get_ident(request) class UserThrottle(SimpleRateThrottle):
"""登录用户访问频率限制"""
scope = "LoginUser" def get_cache_key(self, request, view):return request.user
可以配置redis
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
# "PASSWORD": "密码",
}
}
}
匿名用户的访问频率限制,这里设置在全站下,如下:
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_CLASSES": ["appxx.utils.VisitThrottle"],
"DEFAULT_THROTTLE_RATES":{
"AnonymousUser": "3/m", # 匿名用户一分钟可以访问3次,秒(s)、分(m)、时(h)、天(d)
"LoginUser": "10/m", # 登录用户一分钟可以访问10次
}
}
登录用户的访问频率设置在单独的视图中,而视图依赖身份认证才能辨别用户是否登陆了,所以设置如下:
class BookViewSet(viewsets.ModelViewSet):
authentication_classes = [TokenAuthentication]
throttle_classes = [UserThrottle]
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer
用户身份认证如下:
from rest_framework import authentication
from rest_framework import exceptionsfrom appxx import models class TokenAuthentication(authentication.BaseAuthentication):
"""身份认证"""
def authenticate(self, request):
token = request.GET.get("token")
obj = models.UserAuthToken.objects.filter(token=token).first()
if not obj:
raise exceptions.AuthenticationFailed("验证失败!")
else:
return (obj.user.username, obj.token)