2.认证、权限、访问频率
表结构设计:
vim models.py
1 from django.db import models 2 3 4 #用户信息表 5 class UserInfo(models.Model): 6 user_type_choices = ( 7 (1,'普通用户'), 8 (2,'VIP'), 9 (3,'SVIP'), 10 ) 11 user_type = models.IntegerField(choices=user_type_choices) 12 username = models.CharField(max_length=32,unique=True) 13 password = models.CharField(max_length=64) 14 15 16 #用户token表,认证是通过token进行认证的 17 class UserToken(models.Model): 18 user = models.OneToOneField(to='UserInfo') #关联用户信息表 19 token = models.CharField(max_length=64)
1.全局配置:vim settings.py
具体代码:
1 REST_FRAMEWORK = { 2 # 全局使用的认证类,列表形式,可以写多个,在视图里面应用 3 "DEFAULT_AUTHENTICATION_CLASSES":['api.utils.auth.FirstAuthtication','api.utils.auth.Authtication', ], 4 # "DEFAULT_AUTHENTICATION_CLASSES":['api.utils.auth.FirstAuthtication', ], 5 # "UNAUTHENTICATED_USER":lambda :"匿名用户" 6 "UNAUTHENTICATED_USER":None, # 匿名,request.user = None 7 "UNAUTHENTICATED_TOKEN":None,# 匿名,request.auth = None 8 #全局使用的权限类,可以写多个,视图里面应用 9 "DEFAULT_PERMISSION_CLASSES":['api.utils.permission.SVIPPermission'], 10 #全局使用的访问频率类,可以写多个,视图里面应用 11 "DEFAULT_THROTTLE_CLASSES":["api.utils.throttle.UserThrottle"], 12 "DEFAULT_THROTTLE_RATES":{ 13 "Luffy":'3/m', 14 "LuffyUser":'10/m', 15 } 16 }

2.对应的类全部放在新建的目录utils,便于统一管理

其中auth.py为认证类,源代码如下:
1 from rest_framework import exceptions 2 from api import models 3 from rest_framework.authentication import BaseAuthentication 4 5 #在这里定义了两个认证类,然后分别写了两个不同的规则,在视图中需要什么认证则套用什么规则。 6 7 8 #第一个认证类 9 class FirstAuthtication(BaseAuthentication): 10 def authenticate(self,request): 11 pass 12 13 def authenticate_header(self, request): 14 pass 15 16 #第二个认证类 17 class Authtication(BaseAuthentication): 18 def authenticate(self,request): 19 token = request._request.GET.get('token') 20 token_obj = models.UserToken.objects.filter(token=token).first() 21 if not token_obj: 22 raise exceptions.AuthenticationFailed('用户认证失败') 23 # 在rest framework内部会将整个两个字段赋值给request,以供后续操作使用 24 return (token_obj.user, token_obj) 25 26 def authenticate_header(self, request): #这个函数是不要的,里面的内容可以写pass 27 return 'Basic realm="api"'
permission.py为权限类,源代码如下:
1 from rest_framework.permissions import BasePermission 2 3 4 class SVIPPermission(BasePermission): 5 message = "必须是SVIP才能访问" 6 def has_permission(self,request,view): 7 if request.user.user_type != 3: 8 return False 9 return True 10 11 class MyPermission1(BasePermission): 12 13 def has_permission(self,request,view): 14 if request.user.user_type == 3: 15 return False 16 return True
throttle.py为访问频率类,源代码如下:
1 from rest_framework.throttling import BaseThrottle,SimpleRateThrottle 2 3 4 """ 5 import time 6 VISIT_RECORD = {} 7 class VisitThrottle(BaseThrottle): 8 9 def __init__(self): 10 self.history = None 11 12 def allow_request(self,request,view): 13 # 1. 获取用户IP 14 remote_addr = self.get_ident(request) 15 16 ctime = time.time() 17 if remote_addr not in VISIT_RECORD: 18 VISIT_RECORD[remote_addr] = [ctime,] 19 return True 20 history = VISIT_RECORD.get(remote_addr) 21 self.history = history 22 23 while history and history[-1] < ctime - 60: 24 history.pop() 25 26 if len(history) < 3: 27 history.insert(0,ctime) 28 return True 29 30 # return True # 表示可以继续访问 31 # return False # 表示访问频率太高,被限制 32 33 def wait(self): 34 # 还需要等多少秒才能访问 35 ctime = time.time() 36 return 60 - (ctime - self.history[-1]) 37 38 """ 39 #上面注释段为通过自己的方式实现,掌握原理 40 #下面是restframework内置提供的,很简单,通常用内置提供的就可以了 41 42 from rest_framework.throttling import BaseThrottle,SimpleRateThrottle 43 class VisitThrottle(SimpleRateThrottle): 44 scope = "Luffy" 45 46 def get_cache_key(self, request, view): 47 return self.get_ident(request) 48 49 50 class UserThrottle(SimpleRateThrottle): 51 scope = "LuffyUser" 52 53 def get_cache_key(self, request, view): 54 return request.user.username
3.编辑view.py视图函数
1 from django.shortcuts import render,HttpResponse 2 from django.http import JsonResponse 3 from rest_framework.views import APIView 4 from rest_framework.request import Request 5 from rest_framework import exceptions 6 from rest_framework.authentication import BasicAuthentication 7 from api.utils.permission import SVIPPermission 8 from api.utils.permission import MyPermission1 9 from api.utils.throttle import VisitThrottle 10 from api import models 11 12 13 ORDER_DICT = { 14 1:{ 15 'name': "媳妇", 16 'age':18, 17 'gender':'男', 18 'content':'...' 19 }, 20 2:{ 21 'name': "老狗", 22 'age':19, 23 'gender':'男', 24 'content':'...。。' 25 }, 26 } 27 28 29 def md5(user): 30 import hashlib 31 import time 32 ctime = str(time.time()) 33 m = hashlib.md5(bytes(user,encoding='utf-8')) 34 m.update(bytes(ctime,encoding='utf-8')) 35 return m.hexdigest() 36 37 38 39 class AuthView(APIView): 40 """ 41 用于用户登录认证 42 """ 43 authentication_classes = [] 44 permission_classes = [] 45 throttle_classes = [VisitThrottle,] 46 47 def post(self,request,*args,**kwargs): 48 49 ret = {'code':1000,'msg':None} 50 try: 51 user = request._request.POST.get('username') 52 pwd = request._request.POST.get('password') 53 obj = models.UserInfo.objects.filter(username=user,password=pwd).first() 54 if not obj: 55 ret['code'] = 1001 56 ret['msg'] = "用户名或密码错误" 57 # 为登录用户创建token 58 token = md5(user) 59 # 存在就更新,不存在就创建 60 models.UserToken.objects.update_or_create(user=obj,defaults={'token':token}) 61 ret['token'] = token 62 except Exception as e: 63 ret['code'] = 1002 64 ret['msg'] = '请求异常' 65 66 return JsonResponse(ret) 67 68 69 70 class OrderView(APIView): 71 """ 72 订单相关业务(只有SVIP用户有权限) 73 """ 74 75 def get(self,request,*args,**kwargs): 76 # request.user 77 # request.auth 78 self.dispatch 79 ret = {'code':1000,'msg':None,'data':None} 80 try: 81 ret['data'] = ORDER_DICT 82 except Exception as e: 83 pass 84 return JsonResponse(ret) 85 86 87 88 class UserInfoView(APIView): 89 """ 90 订单相关业务(普通用户、VIP) 91 """ 92 permission_classes = [MyPermission1, ] 93 94 def get(self,request,*args,**kwargs): 95 return HttpResponse('用户信息')

浙公网安备 33010602011771号