setting中的配置:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
REST_FRAMEWORK = { # 全局使用认证组件配置 'DEFAULT_AUTHENTICATION_CLASSES': ['app01.my_author.TokenAuth'], # 全局使用权限组件配置 'DEFAULT_PERMISSION_CLASSES': ['app01.my_author.MyPermission'], # 全局使用频率组件配置 'DEFAULT_THROTTLE_RATES': { 'throttle_by_ip': '1/m', 'anon': None, }, 'DEFAULT_THROTTLE_CLASSES': ['app01.my_author.MyThrottle'], }
一、权限组件:
针对特殊的功能只能是特殊身份的用户才能访问
1、models中的类:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class User(models.Model): id = models.AutoField(primary_key=True) user = models.CharField(max_length=20) password = models.CharField(max_length=20) choice = ((1, '超级用户'), (2, '普通用户'), (3, '黑粉用户')) user_type = models.IntegerField(default=2, choices=choice) # 权限依据 class Usertoken(models.Model): user = models.OneToOneField(to='User', on_delete=models.CASCADE) token = models.CharField(max_length=64)
2、权限判定类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from rest_framework.permissions import BasePermission class MyPermission(BasePermission): def has_permission(self, request, view): print(request.user) if request.user.user_type == 1: return True else: self.message = '你还不是超级用户,无权限访问。当前身份%s' % request.user.get_user_type_display() return False
3、登录和视图类及路由同认证权限(上篇)
二、频率权限:
频率权限:控制一个用户/ip/..在一定时间内的访问次数。
频率权限实现控制的逻辑
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 老师的含有逻辑的代码 # class MyThrottling(BaseThrottle): # VISIT_RECORD = {} # def __init__(self): # self.history=None # def allow_request(self, request, view): # # 频率控制的逻辑 # # 某个ip地址一分钟只能访问三次 # # {ip地址1:[第三次访问的时间,第二次访问的时间,第一次访问的时间],ip地址2:[]} # # (1)取出访问者ip # # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走 # # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间, # # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过 # # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败 # #代码实现 # # (1)取出访问者ip # # print(request.META) # ip = request.META.get('REMOTE_ADDR') # import time # ctime = time.time() # # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问 # if ip not in self.VISIT_RECORD: # self.VISIT_RECORD[ip] = [ctime, ] # return True # #self.history当前访问者访问的时间列表 # self.history = self.VISIT_RECORD.get(ip) # # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间, # #[1s,20s,30s] # while self.history and ctime - self.history[-1] > 60: # self.history.pop() # # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过 # # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败 # if len(self.history) < 3: # self.history.insert(0, ctime) # return True # else: # return False # def wait(self): # import time # ctime = time.time() # return 60 - (ctime - self.history[-1])
1、同权限组件继承BaseThrottle基类自己写的频率认证组件:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import time from rest_framework.throttling import BaseThrottle, SimpleRateThrottle class MyThrottle(BaseThrottle): list_dic = {} def __init__(self): self.history = None def allow_request(self, request, view): print(self.list_dic) scope = request.META.get('REMOTE_ADDR', None) time_ = time.time() if scope not in MyThrottle.list_dic: self.list_dic[scope] = [] self.list_dic[scope].insert(0, time_) return True self.history = self.list_dic[scope] list_li = self.list_dic[scope] if len(list_li) < 3: list_li.insert(0, time_) return True first_time = list_li.pop() list_li.insert(0, time_) self.list_dic[scope] = list_li if time_ - first_time > 60: return True else: return False def wait(self): ctime = time.time() return 60 - (ctime - self.history[-1])
2、通过继承SimpleRateThrottle基类来实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#drf给我们提供的频率控制类 from rest_framework.throttling import SimpleRateThrottle class MyThrottling(SimpleRateThrottle): scope='throttle_by_ip' # 必须覆盖的方法(控制按ip、用户还是其他来限制频率的方法) def get_cache_key(self, request, view): self.get_ident(request) return request.META.get('REMOTE_ADDR')