Django - DRF节流组件

  • 作者:lwj
  • 分类:Django
  • 发表日期:2021-12-11 16:10:55
  • 阅读(53)
  • 评论(0)

节流类似于权限,因为它确定请求是否应该被授权。节流阀表示一种临时状态,用于控制客户端可以向 API 发出的请求速率


如何识别用户

    HTTP报头的X-Forwarded-For和REMOTE_ADDRWSGI变量被用来唯一地标识为节流客户端的IP地址。如果X-Forwarded-For标头存在,则将使用它,否则将使用REMOTE_ADDR来自 WSGI 环境的变量值
    如果您需要严格识别唯一的客户端 IP 地址,您需要首先通过设置NUM_PROXIES设置来配置 API 运行的应用程序代理的数量。此设置应该是零或更多的整数。如果设置为非零,则X-Forwarded-For一旦首先排除了任何应用程序代理 IP 地址,客户端 IP 将被标识为标头中的最后一个 IP 地址。如果设置为零,则该REMOTE_ADDR值将始终用作标识 IP 地址
    重要的是要了解,如果您配置了该NUM_PROXIES设置,那么位于唯一NAT网关后面的所有客户端都将被视为单个客户端
    X-Forwarded-For可以在此处找到有关标头如何工作以及识别远程客户端 IP 的更多上下文

节流策略

全局配置流量控制(可以zzaisetting.py使用DEFAULT_THROTTLE_CLASSESDEFAULT_THROTTLE_RATES设置全局设置默认限制策略)

注:所用的速率的描述DEFAULT_THROTTLE_RATES可以包括secondminutehourday作为节流段

# DRF的所有配置项
REST_FRAMEWORK = {
    # 限流配置
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',   # 匿名用户
        'rest_framework.throttling.UserRateThrottle'    # 登录用户
    ),
    # 限流频次
    'DEFAULT_THROTTLE_RATES': {
        'anon': '200/day',                                 # 匿名用户每天可以请求200次
        'user': "400/day",                                 # 登录用户每天可以请求400次请求
        'card_throttle': '2/minute',                       # 自定义的请求频次(每分钟2次),在视图中关联
    },
}

视图流量控制(使用APIView基于类的视图在每个视图或每个视图集的基础上设置限制策略)

# coding: utf-8
# Author: sitVen

from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, AllowAny, IsAdminUser
from rest_framework.authentication import TokenAuthentication
from rest_framework.throttling import ScopedRateThrottle

from .models import Card
from .serializers import CardSerializer

class CardViewSet(ModelViewSet):
    queryset = Card.objects.all()
    serializer_class = CardSerializer

    """指定当前视图限流"""
    # ScopedRateThrottle: 限制用户对于每个视图的访问频次,使用ip或user id
    throttle_classes = [ScopedRateThrottle]
    # 不同的视图,设置throttle_scope, 需要和setting.REST_FRAMEWORK.DEFAULT_THROTTLE_RATES对应
    throttle_scope = 'card_throttle'

    """指定当前视图身份认证"""
    authentication_classes = [TokenAuthentication]   # token认证
    """指定当前视图访问权限"""
    permission_classes = [IsAuthenticated]           # 仅通过认证的用户

    def get(self, request, pk, *args, **kwargs):
        queryset = self.get_object()
        serializer = CardSerializer(instance=queryset)
        return Response(data={"data": serializer.data, "msg": "成功"})

当请求频率超过限流配置时:

觉得不错,支持一下!

提交评论

您尚未登录,登录之后方可评论~ 登录 or 注册

评论列表

暂无评论
返回顶部

建议反馈

1. 可在博文底部留言评论

2. 发邮件到i_suichuan@163.com