认证 权限 频率控制 组件
rest_framework组件
认证组件
局部认证
在需要认证的视图类里加上authentication_classes = [认证组件1类名,认证组件2类名....]
注意:这个类要放在单独的py文件中,(如果放在view中,全局配置无法使用)
验证通过(布尔值),可以返回两个值,一个给了request.user,一个给了request.auth
choice的用法:
-拿出数字对应的中文:get_字段名_dispaly()
示例如下:
seralizers.py
from rest_framework import serializers
from app01 import models
class PublishSerializers(serializers.ModelSerializer):
class Meta:
model = models.Publish
fields = '__all__'
auth.py
from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from app01 import models
class TokenAuth(BaseAuthentication):
def authenticate(self,request):
'''authenticate'''
# 验证条件根据需求设置(此示例为需要有token值)
token = request.GET.get('token')
token_obj = models.Token.objects.filter(token=token).first()
if not token_obj:
# 如果验证失败,需抛出AuthenticationFailed异常
raise exceptions.AuthenticationFailed("验证失败!")
else:
user = token_obj.user
# 如果验证成功,需要返回一个元组,分别是用户以及验证类的实例对象,然后源码内会赋值给request.user和request.auth
return user,token_obj
views.py
def get_random(name):
import hashlib
import time
md=hashlib.md5()
md.update(bytes(str(time.time()),encoding='utf-8'))
md.update(bytes(name,encoding='utf-8'))
return md.hexdigest()
class Login(APIView):
def post(self,reuquest):
back_msg={'status':1001,'msg':None}
try:
name=reuquest.data.get('name')
pwd=reuquest.data.get('pwd')
user=models.User.objects.filter(username=name,password=pwd).first()
if user:
token=get_random(name)
models.UserToken.objects.update_or_create
(user=user,defaults={'token':token})
back_msg['status']='1000'
back_msg['msg']='登录成功'
back_msg['token']=token
else:
back_msg['msg'] = '用户名或密码错误'
except Exception as e:
back_msg['msg']=str(e)
return Response(back_msg)
class Course(APIView):
authentication_classes = [TokenAuth, ]
def get(self, request):
return HttpResponse('get')
def post(self, request):
return HttpResponse('post')
全局认证
在settings.py中进行如下配置
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.auth.TokenAuth",]
}
这样配置之后,每个视图类都要经过认证成功之后才能执行下一步,
如果有某些方法不需要认证,如login函数,则需要在该视图中单独加入一个配置属性:
authentication_classes = [] #将自身的认证类置空
权限认证
局部认证
permission.py
from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
message = '不是超级用户,查看不了'
def has_permission(self, request, view):
# user_type = request.user.get_user_type_display()
# if user_type == '超级用户':
user_type = request.user.user_type
print(user_type)
if user_type == 1:
return True
else:
return False
views.py
class Course(APIView):
authentication_classes = [TokenAuth, ]
permission_classes = [UserPermission,]
def get(self, request):
return HttpResponse('get')
def post(self, request):
return HttpResponse('post')
这个时候如果权限认证通过,则会继续执行下一步,如果是没通过,则会返回错误信息,如下:
{"detail":"You do not have permission to perform this action."}
局部使用只需要在视图类里加入:
permission_classes = [UserPermission,][]
如果需要自定义错误信息,只需要在视图类里定义一个message属性即可,如下:
message="只有超级用户才能访问"
全局认证
REST_FRAMEWORK = {
# 认证组件
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.auth.TokenAuth",],
# 权限组件
"DEFAULT_PERMISSION_CLASSES": ["app01.permission.VipPermission",],
}
频率认证
为了控制用户对某个url请求的频率,比如,一分钟以内,只能访问三次(节流,访问控制)
局部认证
组件
class MyThrottle(SimpleRateThrottle):
scope='aaa'
def get_cache_key(self, request, view):
return self.get_ident(request)
# 返回什么就以什么来作为次数限制对象
视图
class CourseView(ModelViewSet):
authentication_classes = [self_authentication.UserAuthentication]
permission_classes = [self_permissions.AdminPermission]
throttle_classes = [self_throttle.LookUpCourseRateThrottle]
queryset = models.Course.objects.all()
serializer_class = self_serializers.CourseSerializers
# 自定义提示信息
def throttled(self, request, wait):
from rest_framework import exceptions
class MyThrottled(exceptions.Throttled):
default_detail = '下次访问'
extra_detail_singular = '还剩 {wait} 秒.'
extra_detail_plural = '还剩 {wait} 秒'
raise MyThrottled(wait)
然后在需要进行限制的视图类中加入如下配置:
throttle_classes = [VisitRateThrottle]
在setting中:
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES':{
'aaa':'10/m'
}
}
全局使用
-在setting中写
'DEFAULT_THROTTLE_CLASSES':['app01.self_throttle.LookUpCourseRateThrottle',],
如果在某视图中不需要使用只需要在视图中写
throttle_classes = [] # 将自身的认证类置空
错误信息改成中文显示(如上文视图中所示)
def throttled(self, request, wait):
class MyThrottled(exceptions.Throttled):
default_detail = '傻逼'
extra_detail_singular = '还剩 {wait} 秒.'
extra_detail_plural = '还剩 {wait} 秒'
raise MyThrottled(wait)