权限认证、频率认证

权限组件

# app.models.py:表结构
class User(models.Model):
    user = models.CharField(max_length=32)
    password = models.CharField(max_length=32)
    choice = ((1, '超级用户'), (2, '普通用户'), (3, '穷逼用户'))
    type = models.IntegerField(choices=choice, null=True)

    def __str__(self):
        return self.user
# app.auth.py:认证模块
class MyPermission(BasePermission):
    message = '您的权限不够!'
    def has_permission(self, request, view):
        user = request.user
        if user.type == 1:
            return True
        return False
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('app.auth.MyPermission',),
}
# app.views.py
# 在视图类中通过 permission_classes = [] 来局部禁用
class Books(APIView):# 没有局部禁用默认就有
    def get(self, request):
        return Response({
            'status': 0,
            'message': 'ok',
            'results': []
        })

频率组件

#app.auth.py:认证模块
class MyRateThrottle(SimpleRateThrottle):
    scope = 'xxx'
    def get_cache_key(self, request, view):
        # return self.get_ident(request)
        return request.META.get('REMOTE_ADDR')
#settings.py:配置文件
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'xxx': '3/m' #格式对应上面的scope
    },
    'DEFAULT_THROTTLE_CLASSES': ('app.auth.MyRateThrottle',),
  #这样设置为全局使用
}
# app.views.py:视图层
class Books(APIView):
    def get(self, request):
        return Response({
            'status': 0,
            'message': 'ok',
            'results': []
        })
    # 自定义错误信息
    def throttled(self, request, wait):
        from rest_framework.exceptions import Throttled
        class MyThrottled(Throttled):
            default_detail = '访问频率过快!'
            extra_detail_plural = '{wait}秒后再试!'
        raise MyThrottled(wait)

频率组件原理

class MyThrottle(BaseThrottle):
    # 存放ip与访问时间list的对应关系
    VISIT_RECORD = {}

    def __init__(self):
        # 存放某一访问者历史访问时间的
        self.history = None

    def allow_request(self, request, view):
        # 1) 取出访问者ip
        ip = request.META.get('REMOTE_ADDR')
        # 2) 获取当前时间
        import time
        ctime = time.time()
        # 3) 判断是否是第一次访问
        if ip not in self.VISIT_RECORD:
            self.VISIT_RECORD[ip] = [ctime, ]
            return True
        self.history = self.VISIT_RECORD.get(ip)
        # 4) 当前时间与最开始访问时间间隔超出60s则可以再次访问,移除最开始的访问时间
        while self.history and ctime - self.history[-1] > 60:
            self.history.pop()
        # 5) 访问频率的处理
        if len(self.history) < 3:
            self.history.insert(0, ctime)
            return True
        else:
            return False

    def wait(self):
        import time
        ctime = time.time()
        # 还要等多久才能访问
        return 60 - (ctime - self.history[-1])
原文地址:https://www.cnblogs.com/ShenJunHui6/p/10899025.html