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'})