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)
View Code

 

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 }
View Code

 

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"'
View Code

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
View Code

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
View Code

 

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('用户信息')
View Code

 

posted @ 2018-04-26 12:31  Paco_Pig  阅读(140)  评论(0)    收藏  举报