服务端相关 / 11 限流与过滤

限流与过滤

当前,我们的 Restful Web API 不仅能够提供客户端需要的资源,还实现了认证和权限,可以保证数据的安全。大家在日常中一定有过这样的经历,有些网站免费用户一天只能免费观看 3 部视频,超过就要付费,否则无法观看,另外,如果想找到 2020 年上映的全部电影,只需在检索时选中想要的年份就可以。那么我们搭建的 Restful Web API 能实现类似的功能吗?当然可以,这就涉及到了限流与过滤,接下来,我们就带领大家,一起实现这两个功能。

1.限流的使用方法

有时,为了防止恶意访问,或减轻服务器压力,我们需要对用户的访问频率进行限制。我们可在配置文件中,使用DEFAULT_THROTTLE_CLASSESDEFAULT_THROTTLE_RATES进行全局配置,

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day', # 匿名用户每天可访问100次
        'user': '1000/day' # 通过认证的用户每天可访问1000次
    }
}

DEFAULT_THROTTLE_RATES 可以使用 second, minute, hourday来指明周期。也可以在具体视图中通过 throttle_classess 属性来配置,如

from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView

class ExampleView(APIView):
    throttle_classes = (UserRateThrottle,)
    ...

2. Django Rest framework为我们提供的限流类

2.1 AnonRateThrottle

限制所有匿名未认证用户,不同用户的区分通过识别用户 IP 实现。使用DEFAULT_THROTTLE_RATES['anon'] 来设置频率限制。

2.2 UserRateThrottle

限制认证用户,使用 User id 来区分不同用户。使用 DEFAULT_THROTTLE_RATES['user'] 来设置频率限制。

2.3 ScopedRateThrottle

限制用户对于每个视图的访问频次,使用 ip 或 user id 区分不同用户。

例如:

class ContactListView(APIView):
    throttle_scope = 'contacts'
    ...

class ContactDetailView(APIView):
    throttle_scope = 'contacts'
    ...

class UploadView(APIView):
    throttle_scope = 'uploads'
    ...
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.ScopedRateThrottle',
    ),
    'DEFAULT_THROTTLE_RATES': {
        'contacts': '1000/day',
        'uploads': '20/day'
    }
}

3.实例

from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.throttling import UserRateThrottle

class StudentViewSet(ModelViewSet):
    queryset = StudentsModel.objects.all()
    serializer_class = StudentsSerializer
    authentication_classes = [SessionAuthentication]
    permission_classes = [IsAuthenticated]
    throttle_classes = (UserRateThrottle,)

4.过滤的使用

有时,在访问接口时,需要的是符合一定条件的数据。此时可以通过过滤来实现,Django Rest framework中,可以使用 django-fitlter 来实现过滤功能。在使用该功能前,需要提前安装和注册 django-filter。

在终端输入以下内容完成 django-filter 的安装:

pip install django-filter

在配置文件中配置以下内容:

INSTALLED_APPS = [
    ...
    'django_filters',  # 注册应用
]

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

在视图中添加 filter_fields 属性,指定可以过滤的字段:

class StudentViewSet(ModelViewSet):
    queryset = StudentsModel.objects.all()
    serializer_class = StudentsSerializer
    filter_fields = ('s_age')

此时,可以通过访问 http://127.0.0.1:8000/api/students/?s_age=11 来获取所有年龄为 11 的学生信息。

5.小结

本小节为大家介绍了限流和过滤,通过限流可以限制用户访问接口的频率,起到防止用户恶意访问的作用,过滤功能则是对数据的进一步处理,筛选出符合用户需求的数据或者按照用户的需求,实现返回诸如按一定顺序排列的数据等。