models.py中:
class UserInfo(models.Model): name = models.CharField(max_length=32) psw = models.CharField(max_length=32) user_type_choices = ((1,"普通"),(2,"VIP"),(3,"SVIP")) user_type = models.SmallIntegerField(choices=user_type_choices,default=1) # 新添加一个标识用户权限级别的字段 class Token(models.Model): # Token类用于 认证 user = models.OneToOneField(to="UserInfo",on_delete=models.CASCADE) token = models.CharField(max_length=128)
认证组件:
局部视图认证:
在app01.service.auth.py:
class Authentication(BaseAuthentication): def authenticate(self,request): # authenticate() 这个方法名是固定的 token=request._request.GET.get("token") token_obj=UserToken.objects.filter(token=token).first() if not token_obj: # 检查token是否存在 raise exceptions.AuthenticationFailed("验证失败!") # 认证失败时的固定语法 return (token_obj.user,token_obj) # 认证成功后需要返回一个元组:第一个是用户有关的信息
在views.py:
def get_random_str(user): import hashlib,time ctime=str(time.time()) md5=hashlib.md5(bytes(user,encoding="utf8")) # user是为了“加盐”处理 md5.update(bytes(ctime,encoding="utf8")) return md5.hexdigest() from app01.service.auth import * from django.http import JsonResponse class LoginViewSet(APIView): authentication_classes = [Authentication,] # authentication_classes 是固定写法;需要认证的类都写在后面的列表中 def post(self,request,*args,**kwargs): res={"code":1000,"msg":None} try: user=request._request.POST.get("user") pwd=request._request.POST.get("pwd") user_obj=UserInfo.objects.filter(user=user,pwd=pwd).first() print(user,pwd,user_obj) if not user_obj: res["code"]=1001 res["msg"]="用户名或者密码错误" else: token=get_random_str(user) UserToken.objects.update_or_create(user=user_obj,defaults={"token":token}) # 表中没有就创建,有就更新;# 返回一个元组:第一个是对象,第二个是布尔值(表示create还是update) res["token"]=token except Exception as e: res["code"]=1002 res["msg"]=e return JsonResponse(res,json_dumps_params={"ensure_ascii":False}) # {"ensure_ascii":False} 作用:显示中文
全局视图认证组件:
settings.py配置如下:
REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",] # 写上 认证类的路径 }
权限组件
局部视图权限
在app01.service.permissions.py中:
from rest_framework.permissions import BasePermission class SVIPPermission(BasePermission): message="SVIP才能访问!" # 没有权限时返回的错误信息 def has_permission(self, request, view): if request.user.user_type==3: return True return False # return True就是通过权限认证, return False 即没有权限
在views.py:
from app01.service.permissions import * class BookViewSet(generics.ListCreateAPIView): permission_classes = [SVIPPermission,] # permission_classes 是固定写法;需要校验的权限类都写在后面的列表中(这是局部权限校验) queryset = Book.objects.all() serializer_class = BookSerializers
全局视图权限:
settings.py配置如下:
REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",], "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",] # 写上权限认证类的路径 }
throttle(访问频率)组件
局部视图throttle
在app01.service.throttles.py中:
from rest_framework.throttling import BaseThrottle VISIT_RECORD={} class VisitThrottle(BaseThrottle): def __init__(self): self.history=None def allow_request(self,request,view): # allow_request()是固定的方法名 # 以下为业务逻辑(rest 只处理数据,不处理逻辑) remote_addr = request.META.get(‘REMOTE_ADDR‘) # 客户端的IP地址 print(remote_addr) import time ctime=time.time() if remote_addr not in VISIT_RECORD: VISIT_RECORD[remote_addr]=[ctime,] return True history=VISIT_RECORD.get(remote_addr) self.history=history while history and history[-1]<ctime-60: history.pop() if len(history)<3: history.insert(0,ctime) return True # return True 表示通过验证 else: return False # return False 表示没通过验证 def wait(self): import time ctime=time.time() return 60-(ctime-self.history[-1])
在views.py中:
from app01.service.throttles import * class BookViewSet(generics.ListCreateAPIView): throttle_classes = [VisitThrottle,] # throttle_classes 是固定写法; queryset = Book.objects.all() serializer_class = BookSerializers
全局视图throttle
REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",], "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",], "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",] }
内置throttle类
在app01.service.throttles.py修改为:
class VisitThrottle(SimpleRateThrottle): scope="visit_rate" def get_cache_key(self, request, view): return self.get_ident(request)
settings.py设置:
REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",], "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",], "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",], "DEFAULT_THROTTLE_RATES":{ "visit_rate":"5/m", } }
原文地址:https://www.cnblogs.com/neozheng/p/9589175.html
时间: 2024-11-08 22:40:48