DRF的认证、权限及访问频率限制的简单介绍

认证

  认证的作用是告知api是那个用户在请求。

  需要新建一个UserInfo的Model。

  其实也可以用Form与ModelForm代替。

认证类的简单写法

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from user import models


class MyAuth(BaseAuthentication):

    def authenticate(self, request):
        # 通过唯一标识找到用户
        token = request.query_params.get('token')
        user_obj = models.User.objects.filter(token=token).first()

        if user_obj:
            # 返回:第一个是用户对象,第二个是token的值
            return user_obj, token
        raise AuthenticationFailed('认证失败')

应用1—全局默认配置—所有类都进行认证

REST_FRAMEWORK = {    
    # 后面是认证类在项目中的位置的路径
    "DEFAULT_AUTHENTICATION_CLASSES": ['user.auth.MyAuth']
}

应用2—视图中单独配置

—— 注意:视图中的配置会“覆盖”全局默认配置!如果在视图中设置为空列表,那么这个类就不进行认证了!

from user.auth import MyAuth

class TestView(APIView):

    authentication_classes = [MyAuth]

    def get(self, request):
        return Response({'msg': ok'})

权限

  权限组件的作用是:校验当前访问的用户能否获取到正确的结果。

  特别注意:

    (1)权限组件的使用是建立在认证组件校验成功的前提下的!

    (2)如果用户没有登录,此时它是一个“匿名用户”,匿名用户只能访问不用登录的页面以及进行相关的操作。

权限类的简单写法

from rest_framework.permissions import BasePermission

class VipPermission(BasePermission):
    # 错误的提示
    message = '没有访问权限,请联系管理员'
    
    def has_permission(self, request, view):
        # 这里其实可以跟“权限组件”联系起来~通过用户对象连续跨表找到路由,进行权限的校验
        if not request.auth:
            # 没有认证就没有权限
            return False
# 这里做了简单的校验,其实可以跟权限组件联系起来的
if request.user.vip: return True else: return False

应用—全局配置—所有类都进行权限校验

REST_FRAMEWORK = {
   # 校验 
    "DEFAULT_AUTHENTICATION_CLASSES": ['user.auth.MyAuth'],
    
   # 权限
"DEFAULT_PERMISSION_CLASSES":['user.permission.VipPermission'] }

应用—视图函数中局部配置

from user.permission import VipPermission

class TestView(APIView):
    # authentication_classes = []
    permission_classes = [VipPermission]

—— 注意:视图中的配置会“覆盖”全局默认配置!如果在视图中设置为空列表,那么这个类就不进行权限校验了!

频率限制

  顾名思义,这个组件是用来限制用户访问网站的频率的。

用户自定义频率限制的类

频率限制的类这样写:

from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
import time
from rest_framework import exceptions
visit_record = {}
class VisitThrottle(BaseThrottle):
    # 限制访问时间
    VISIT_TIME = 10
    VISIT_COUNT = 3

    # 定义方法 方法名和参数不能变
    def allow_request(self, request, view):
        # 获取登录主机的id
        id = request.META.get('REMOTE_ADDR')
        self.now = time.time()

        if id not in visit_record:
            visit_record[id] = []

        self.history = visit_record[id]
        # 限制访问时间
        while self.history and self.now - self.history[-1] > self.VISIT_TIME:
            self.history.pop()
        # 此时 history中只保存了最近10秒钟的访问记录
        if len(self.history) >= self.VISIT_COUNT:
            return False
        else:
            self.history.insert(0, self.now)
            return True

    def wait(self):
        return self.history[-1] + self.VISIT_TIME - self.now

在全局中进行的全局配置:

REST_FRAMEWORK = {
   # 校验 
    "DEFAULT_AUTHENTICATION_CLASSES": ['user.auth.MyAuth'],
    
   # 权限
    "DEFAULT_PERMISSION_CLASSES":['user.permission.VipPermission'],

  # 频率限制
  "DEFAULT_THROTTLE_CLASSES":["user.throttles.VisitThrottle",]
}

视图函数中进行的局部配置:

from user.throttles import *

class BookViewSet(generics.ListCreateAPIView):
    throttle_classes = [VisitThrottle,]

queryset
= Book.objects.all() serializer_class = BookSerializers

利用DRF自带的频率限制类

配置:

REST_FRAMEWORK = {
    
    # 认证
    "DEFAULT_AUTHENTICATION_CLASSES": ['user.auth.MyAuth'],
    # 权限
    "DEFAULT_PERMISSION_CLASSES":['user.permission.VipPermission']
    # 频率
    "DEFAULT_THROTTLE_CLASSES": [
        # 处理的类
        'user.throttle.MyThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        # 视图
        "xxxxx": '5/m',
        "x1": '1/s',
    }

}

REST_FRAMEWORK = {

    "DEFAULT_AUTHENTICATION_CLASSES": ['user.auth.MyAuth'],
    "DEFAULT_PERMISSION_CLASSES":['user.permission.VipPermission']
    
    "DEFAULT_THROTTLE_CLASSES": [
        'user.throttle.MyThrottle2',
    ],
    'DEFAULT_THROTTLE_RATES': {
        "xxxxx": '5/m',
        "x1": '1/s',
    }

}

视图:

class TestView(APIView):

    throttle_scope = 'x1'

    def get(self, request):
        return Response({'msg': 'ok'})


class Test2View(APIView):
    throttle_scope = 'xxxxx'

    def get(self, request):
        return Response({'msg': 'ok'})

 

posted on 2019-08-15 15:39  江湖乄夜雨  阅读(396)  评论(0编辑  收藏  举报