认证
认证的作用是告知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('认证失败')
全局默认配置:所有类都进行认证
REST_FRAMEWORK = {
# 后面是认证类在项目中的位置的路径
"DEFAULT_AUTHENTICATION_CLASSES": ['user.auth.MyAuth']
}
视图中单独配置
注意:视图中的配置会“覆盖”全局默认配置,如果在视图中设置为空列表,那么这个类就不进行认证了!
from user.auth import MyAuth
class TestView(APIView):
# 配置认证的类,注意放在列表中
authentication_classes = [MyAuth]
def get(self, request):
return Response({'msg': ok'})
权限
权限组件的作用是:校验当前访问的用户能否获取到正确的结果。
特别注意:
- 权限组件的使用是建立在认证组件校验成功的前提下的!
- 如果用户没有登录,此时它是一个“匿名用户”,匿名用户只能访问不用登录的页面以及进行相关的操作。
权限类的简单写法
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
1.在全局中进行的全局配置
REST_FRAMEWORK = {
# 校验
"DEFAULT_AUTHENTICATION_CLASSES": ['user.auth.MyAuth'],
# 权限
"DEFAULT_PERMISSION_CLASSES":['user.permission.VipPermission'],
# 频率限制
"DEFAULT_THROTTLE_CLASSES":["user.throttles.VisitThrottle",]
}
2.视图中进行的局部配置
from user.throttles import *
class BookViewSet(generics.ListCreateAPIView):
throttle_classes = [VisitThrottle,]
queryset = Book.objects.all()
serializer_class = BookSerializers
二、Django中自带的访问频率限制的类
1.配置
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',
}
}
2.视图中调用
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'})