DRF-认证 权限 频率组件
补充
1 认证 权限 频率组件原理基本相同
2 认证相关:
session cookie token 认证相关的 这里用token
token 1 有时间限制,超时则失效 2 每次登录更换一个token
3 访问频率限制
1 防止同一时间多次访问的黑客攻击,增加服务器压力。
4 我们的解析 认证 权限 频率 是在用户get post等请求之前就做好了的
5 uuid随机数模块,uuid.uuid4()获取随机数
认证 权限 频率组件操作流程
认证需要建立user表和token表
# 用户表
class User(models.Model):
user=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
type=((1,"VIP"),(2,"SVIP"),(3,"SSSVIP"))
user_type=models.IntegerField(choices=type) # token表
class UserToken(models.Model):
user=models.OneToOneField("User")
token=models.CharField(max_length=128)
用户登录视图添加token
from app01.models import User,UserToken class LoginView(APIView):
"""
1000:成功
1001:用户名或者密码错误
1002:异常错误
"""
def post(self,request): response = {"code": 1000, "msg": None, "user": None}
try:
print(request.data)
user = request.data.get("user")
pwd = request.data.get("pwd") user = User.objects.filter(user=user, pwd=pwd).first()
import uuid
random_str = uuid.uuid4()
if user: UserToken.objects.update_or_create(user=user, defaults={"token": random_str})
response["user"] = user.user
response["token"] = random_str
else:
response["code"] = 1001
response["msg"] = "用户名或者密码错误" except Exception as e:
response["code"]=1002
response["msg"]=str(e) return Response(response)
认证自定义的模块
其中继承 BaseAuthentication除了类本生加的功能外还继承了header方法,如果不继承需要自己写一个header方法,否则会报错!
from app01.models import UserToken
from rest_framework.exceptions import AuthenticationFailed from rest_framework.authentication import BaseAuthentication class UserAuth(BaseAuthentication): def authenticate(self,request): token=request.query_params.get("token") usertoken=UserToken.objects.filter(token=token).first()
if usertoken:
return usertoken.user,usertoken.token
else:
raise AuthenticationFailed("认证失败!")
权限组件自定义的模块
from rest_framework.permissions import AllowAny class SVIPPermission(object):
message="您没有访问权限!"
def has_permission(self,request,view):
if request.user.user_type >= 2:
return True
return False
频率组件自定义的模块
以一分钟访问3次为例
from rest_framework.throttling import BaseThrottle VISIT_RECORD={}
class VisitThrottle(BaseThrottle): def __init__(self):
self.history=None def allow_request(self,request,view):
remote_addr = request.META.get('REMOTE_ADDR')
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
else:
return False def wait(self):
import time
ctime=time.time()
return 60-(ctime-self.history[-1])
在全局中的定制
REST_FRAMEWORK={
# 解析器组件
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
),
# 认证组件
'DEFAULT_AUTHENTICATION_CLASSES': (
'app01.utils.auth_class.UserAuth', ),
# 权限组件
'DEFAULT_PERMISSION_CLASSES': (
'app01.utils.permission_class.SVIPPermission',
),
# 频率组件
'DEFAULT_THROTTLE_CLASSES': (),
}
在局部中的定制及在视图中的使用
# 导入自定义的认证功能类
from app01.utils.auth_class import UserAuth
# 导入自定义的权限功能类
from app01.utils.permission_class import SVIPPermission
# 导入自定义的频率功能类
from app01.utils.throttle_classes import VisitThrottle from rest_framework.throttling import BaseThrottle
class VisitThrottle(BaseThrottle):
def allow_request(self,request,view):
"""
限制IP每分钟访问不能超过3次
:param request:
:param view:
:return:
"""
print(self.get_ident(request))
remote_addr = request.META.get('REMOTE_ADDR')
print("REMOTE_ADDR",remote_addr)
return False class BookView(APIView):
# 认证
# authentication_classes = [UserAuth]
# 权限
# permission_classes = [SVIPPermission]
# 频率
throttle_classes = [VisitThrottle] def get(self,request):
'''
查看所有书籍
:param request:
:return:
''' print(request.user,request.auth) book_list=Book.objects.all()
serializer=BookSerializer(book_list,many=True)
return Response(serializer.data) def post(self,request):
'''
添加一条书籍
:param request:
:return:
'''
print(request.data) serializer=BookSerializer(data=request.data,many=False) if serializer.is_valid():
serializer.save() # create操作 return Response(serializer.data)
else:
return Response(serializer.errors) class SBookView(APIView): def get(self,request,id):
edit_obj=Book.objects.get(pk=id)
serializer=BookSerializer(edit_obj,many=False)
return Response(serializer.data) def put(self,request,id):
edit_obj = Book.objects.get(pk=id)
serializer=BookSerializer(data=request.data,instance=edit_obj)
if serializer.is_valid():
serializer.save() # edit_obj.update(request.data)
return Response(serializer.data)
else:
return Response(serializer.errors) def delete(self,request,id):
edit_obj = Book.objects.get(pk=id).delete()
return Response("")
以认证为例的源码解析
//用户访问,当经过dispath时
1 def dispatch(self, request, *args, **kwargs):
self.initial(request, *args, **kwargs)
initial()是我们的解析 认证 权限 频率功能
2 在initial函数中
def initial(self, request, *args, **kwargs):
# 执行认证功能
self.perform_authentication(request)
# 执行权限功能
self.check_permissions(request)
# 执行频率功能
self.check_throttles(request)
3 我们走perform_authentication(request)认证功能
def perform_authentication(self, request):
request.user
从这里我们要从request实例中找user方法
4 我们通过request实例对象找到它的类中的user方法
def dispatch(self, request, *args, **kwargs):
request = self.initialize_request(request, *args, **kwargs)
def initialize_request(self, request, *args, **kwargs)
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
class Request(object):
def user(self):
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate()
return self._user
5 在_authenticate()中:
def _authenticate(self):
# 和解析器一样,获得[UserAuth()] 获得顺序:当前视图类下-->全局setting-->默认default
for authenticator in self.authenticators:
try:
# 执行authenticate方法进行验证,返回元组/空 或抛出一个异常
user_auth_tuple = authenticator.authenticate(self)
except exceptions.APIException:
self._not_authenticated()
raise
# 如果返回一个元组则执行下面的语句
if user_auth_tuple is not None:
self._authenticator = authenticator
self.user, self.auth = user_auth_tuple
# 这里有个坑,如果返回元组,则直接结束_authenticate函数,不继续循环了!
return
这里如果不抛异常则进入下一个组件
DRF-认证 权限 频率组件的更多相关文章
- 实战-DRF快速写接口(认证权限频率)
实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestframework3.13 测试工具 Postma ...
- restful知识点之三restframework认证-->权限-->频率
认证.权限.频率是层层递进的关系 权限业务时认证+权限 频率业务时:认证+权限+频率 局部认证方式 from django.conf.urls import url,include from djan ...
- 8) drf 三大认证 认证 权限 频率
一.三大认证功能分析 1)APIView的 dispath(self, request, *args, **kwargs) 2)dispath方法内 self.initial(request, *ar ...
- DRF 认证 权限 视图 频率
认证组件 使用:写一个认证类,继承BaseAuthentication 在类中写authenticate方法,把request对象传入 能从request对象中取出用户携带的token根据token判 ...
- rest framework 认证 权限 频率
认证组件 发生位置 APIview 类种的 dispatch 方法执行到 initial 方法 进行 认证组件认证 源码位置 rest_framework.authentication 源码内部需要 ...
- (四) DRF认证, 权限, 节流
一.Token 认证的来龙去脉 摘要 Token 是在服务端产生的.如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端.前端可以在每次请求的时候带上 To ...
- 三 drf 认证,权限,限流,过滤,排序,分页,异常处理,接口文档,集xadmin的使用
因为接下来的功能中需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员. python manage.py createsuperuser 创建管理员以后,访问admin站点 ...
- Django rest_framework----认证,权限,频率组件
认证 from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions impor ...
- rest-framework框架——认证、权限、频率组件
一.rest-framework登录验证 1.models.py添加User和Token模型 class User(models.Model): name = models.CharField(max ...
随机推荐
- Luogu5284 十二省联考2019字符串问题(后缀树+拓扑排序)
对反串建SAM弄出后缀树,每个b串通过倍增定位其在后缀树上对应的节点,根据其长度将节点拆开.然后每个a串也找到对应的节点,由该节点向表示a串的节点连边,再把所给的边连上跑拓扑排序即可. #includ ...
- 微软发布云端基因服务:推动AI驱动的精准医疗
微软发布云端基因服务:推动AI驱动的精准医疗 2018年03月07日 00:00:00 微软研究院AI头条 阅读数:117 版权声明:本文为博主原创文章,未经博主允许不得转载. https:// ...
- SublimeText 3 常见快捷键
·F12 跳转至预定义 ·F11 全屏模式 ·Ctrl+A 本文全选 ·Ctrl+F 打开底部搜索框,查找关键字. ·Ctrl+D 本文件选中光标选中的单词 ·Ctrl+L 选中光标所在一行 ·C ...
- MYSQL日期相关操作
*******MYSQL中取当前周/月/季/年的第一天与最后一天******* 当年第一天: SELECT DATE_SUB(CURDATE(),INTERVAL dayofyear(now())-1 ...
- # 机器学习算法总结-第八天(SKlearn中的kmeans/随机森林)
随机森林 这篇好好看看怎么调参的 我调的最佳参数如下,准确率为0.8428671546929973,细节看上篇文章: alg = RandomForestClassifier(n_estimators ...
- Linux服务器centos7系统下搭建Jenkins
Jenkins是什么? Jenkins是开源CI&CD软件领导者, 提供超过1000个插件来支持构建.部署.自动化, 满足任何项目的需要. 所以现在是越来越多的公司都在使用Jenkins做持续 ...
- git的使用(win7 64位)
下载安装 1.官方下载网址:https://git-scm.com/downloads: 2.安装十分简单,按照默认配置,一直点击next,最后点击install,即安装成功: 3.安装成功之后,则自 ...
- 理解JVM之内存分配以及分代思想实现
1.基本内存分批策略 大多数情况在新生代Eden区分配,如果启动了本地线程分配缓冲,将按线程优先在TLAB(线程私有缓冲区)上分配.当Eden区域没有足够的空间时将发起一次Minor GC. 值得注意 ...
- Vue获取数据渲染完成事件
主要代码是这两坨 this.nextTick(function(){ alert('数据已经更新') }); this.$nextTick(function(){ alert('v-for渲染已经完成 ...
- Cisco建网3层模型
网络畅通条件: 沿途路由器必须知道到达目标网络下一跳给谁 沿途路由器必须知道回来的数据包下一跳给谁 Router0~2均手动添加了到192.168.1.0/24网段的路由 分析1:PC0 ping B ...