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 ...
随机推荐
- CentOS7 服务器连接超时自动断开问题解决
背景 现在的客户们都开始使用云服务器了,还要通过堡垒机才给访问权限,这种方式访问方式以前都是银行的"专利",不过也间接说明其他行业的信息化也越来越普及了.今天主要是因为分配给我的这 ...
- (十二)Activitivi5之流程控制网关:排他
一.概念 所谓排他网关 顾名思义 执行到该网关,根据条件只能走一条执行线 二.案例 当流程走到“学生请假”任务节点的时候, /** * 完成任务 */ @Test public void test_c ...
- 【转】[STL]vector和deque的内存释放(clear)
vector的clear成员函数可以清除vector中的元素,使其大小减至0.但它却不能减小vector占用的内存. [cpp] view plain copy int main() { vector ...
- ligerui.grid.extend.rowSpan
扩展LigerUI的Grid中的相同列合并行功能,代码如下:$.extend($.ligerui.controls.Grid.prototype, { _getHtmlFromData:functio ...
- fiddle--APP弱网测试
一.安装Fiddler 网上说要先安装.NET Framwork4,应该是由于本机已装,所以在安装Fiddler时并没有相关提示. Fiddler安装包:https://www.telerik.com ...
- 案例:selenium实现登录百度(如有验证码,需要手动输入)
func.py https://www.cnblogs.com/andy9468/p/10899508.html baidu_login.py中(如有验证码,需要手动输入) # 导入webdriver ...
- 【Linux】Linux基本命令
一.Linux关机 shutdown -h 10 10min后关机 shutdown -h 10:00 10:00关机 shutdown -h now 或 halt 或 poweroff 立即关机 ...
- 重构drf项目后的manage.py报错的问题
Python3.6 用Django连接mysql一直报错django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer ...
- openpyxl 设置单元格颜色
在处理excel数据格式的时候,需要对特定单元格进行颜色标注,方便相关人员查看 醒目 # -*- coding: utf-8 -*- from openpyxl import load_workboo ...
- 《浏览器工作原理与实践》<08>调用栈:为什么JavaScript代码会出现栈溢出?
在上篇文章中,我们讲到了,当一段代码被执行时,JavaScript 引擎先会对其进行编译,并创建执行上下文.但是并没有明确说明到底什么样的代码才算符合规范. 那么接下来我们就来明确下,哪些情况下代码才 ...