DRF 认证、权限、限制
DRF 认证、权限、限制
认证:
定义一个用户表和一个保存用户的Token表

# ======================day96======================= class UserInfo(models.Model):
username = models.CharField(max_length=16,unique=True)
password = models.CharField(max_length=32) type = models.SmallIntegerField(
choices=((1,"普通用户"),(2,"VIP用户")),
default=1
) class Token(models.Model):
token = models.CharField(max_length=128)
user = models.OneToOneField(to="UserInfo",on_delete=models.CASCADE)

定义一个登陆视图:

# 生成Token的函数
def get_token_code(username):
"""
根据用户名和时间戳来生成永不相同的token随机字符串
:param username: 字符串格式的用户名
:return: 字符串格式的Token
""" import time
import hashlib timestamp = str(time.time())
m = hashlib.md5(username.encode("utf-8"))
# md5 要传入字节类型的数据
m.update(timestamp.encode("utf-8"))
return m.hexdigest() # 将生成的随机字符串返回 # 登陆视图 class LoginView(APIView):
'''
登陆检测试图。
1,接收用户发过来的用户名和密码数据
2,校验用户密码是否正确
- 成功就返回登陆成功,然后发Token
- 失败就返回错误提示
''' def post(self,request):
res = {"code":0}
# 从post 里面取数据
print(request.data)
username = request.data.get("username")
password = request.data.get("password")
# 去数据库查询
user_obj = models.UserInfo.objects.filter(
username = username,
password = password
).first()
if user_obj:
# 登陆成功
# 生成Token
token = get_token_code(username)
# 将token保存
# 用user = user_obj 这个条件去Token表里查询。
# 如果又记录就更新default里传的参数,没有记录就用default里传的参数创建一条数据。
models.Token.objects.update_or_create(defaults={"token":token},user = user_obj)
# 将token返回给用户
res["token"] = token
else:
# 登陆失败
res["code"] = 1
res["error"] = "用户名或密码错误"
return Response(res)

新建一个utils文件夹 下面放一些组件:
定义一个MyAuth认证类:

"""
这里放自定义的认证类
"""
from rest_framework.authentication import BaseAuthentication
from app01 import models
from rest_framework.exceptions import AuthenticationFailed class MyAuth(BaseAuthentication): def authenticate(self, request):
# print(request.method)
if request.method in ["POST","PUT","DELETE"]:
# 如果请求是post,put,delete三种类型时
# 获取随用户请求发来的token随机码
token = request.data.get("token")
# 然后去数据库查询有没有这个token
token_obj = models.Token.objects.filter(token=token).first()
if token_obj:
# 如果存在,则说明验证通过,以元组形式返回用户对象和token
return token_obj.user,token
else:
# 不存在就直接抛错
raise AuthenticationFailed("无效的token")
else:
# 这一步的else 是为了当用户是get请求时也可获取数据,并不需要验证token.
return None,None

视图级别认证:
class CommentViewSet(ModelViewSet):
queryset = models.Comment.objects.all()
serializer_class = app01_serializers.CommentSerializer
authentication_classes = [MyAuth,]
permission_classes = [MyPermission,]
全局级别认证:需要在settings.py文件设置:

# REST FRAMEWORK 相关的配置
REST_FRAMEWORK = {
# 关于认证的全局配置
# "DEFAULT_AUTHENTICATION_CALSSES": ["app01.utils.auth.MyAuth",],
# "DEFAULT_PERMISSION_CLASSES" : ["app01.utils.permission.MyPermission"],
# "DEFAULT_THROTTLE_CLASSES" : ["app01.utils.throttle.MyThrottle",],
"DEFAULT_THROTTLE_CLASSES" : ["app01.utils.throttle.VisitThrottle",],
"DEFAULT_THROTTLE_RATES":{
"XXX":"5/m",
}
}

权限:
只有VIP用户才能看的内容:
自定义权限类:

'''
自定义的权限类
''' from rest_framework.permissions import BasePermission class MyPermission(BasePermission):
message = "sorry,您没有权限"
def has_permission(self, request, view):
# 内置封装的方法
'''
判断该用户有没有权限
'''
# 判断用户是不是VIP用户
# 如果是VIP用户就返回True
# 如果是普通用户就返会Flase if request.method in ["POST","PUT","DELETE"]:
# print(111)
print(request.user.username)
print(request.user.type)
print(type(request.user.type))
if request.user.type == 2: # 是VIP用户
print(2222)
return True
else:
return False
else:
return True def has_object_permission(self, request, view, obj):
# 用来判断针对的obj权限:
# 例如:是不是某一个人的评论
'''
只有评论人是自己才能删除选定的评论
'''
if request.method in ["PUT","DELETE"]:
print(obj.user.username)
print(request.user.username)
if obj.user == request.user:
# 表示当前评论对象的用户就是登陆用户
return True
else:
return False
else:
return True

视图级别配置:
class CommentViewSet(ModelViewSet):
queryset = models.Comment.objects.all()
serializer_class = app01_serializers.CommentSerializer
authentication_classes = [MyAuth,]
permission_classes = [MyPermission,]
全局级别配置:

# REST FRAMEWORK 相关的配置
REST_FRAMEWORK = {
# 关于认证的全局配置
# "DEFAULT_AUTHENTICATION_CALSSES": ["app01.utils.auth.MyAuth",],
# "DEFAULT_PERMISSION_CLASSES" : ["app01.utils.permission.MyPermission"],
# "DEFAULT_THROTTLE_CLASSES" : ["app01.utils.throttle.MyThrottle",],
"DEFAULT_THROTTLE_CLASSES" : ["app01.utils.throttle.VisitThrottle",],
"DEFAULT_THROTTLE_RATES":{
"XXX":"5/m",
}
}

限制:
自定义限制类:

'''
自定义的访问限制类
''' from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
import time # =============================
# DIC = {}
#
# class MyThrottle(BaseThrottle):
# def allow_request(self, request, view):
# '''
# 返回True就放行,返回False表示被限制了
# '''
#
# # 获取当前访问的ip地址
# ip = request.META.get("REMOTE_ADDR")
#
# # 获取当前时间
# now = time.time()
#
# # 判断当前ip是否有访问记录
# if ip not in DIC:
# DIC[ip] = [] # 如果没有访问记录初始化一个空的访问历史列表
#
# # 高端操作
# history = DIC[ip]
# # 当当前ip存在访问记录,且现在的访问时间比最初的一次访问时间大于10秒
# while history and now - history[-1] > 10:
# history.pop() # 删掉历史列表中的最后一个记录
# # 判断最近一分钟的访问次数是否超过了阈值(3次)
# if len(history)>=3:
# return False
# else:
# # 把这一次的访问时间加到访问历史列表的第一位
# DIC[ip].insert(0,now)
# return True # ==============================
# 以上代码等同于一下代码
class VisitThrottle(SimpleRateThrottle):
scope = 'XXX' def get_cache_key(self, request, view):
return self.get_ident(request) # 求当前访问的IP

视图级别:

from app01.utils.auth import MyAuth
from app01.utils.permission import MyPermission
from app01.utils.throttle import SimpleRateThrottle
# from app01.utils.throttle import
class CommentViewSet(ModelViewSet):
queryset = models.Comment.objects.all()
serializer_class = app01_serializers.CommentSerializer
authentication_classes = [MyAuth,]
permission_classes = [MyPermission,]

全局级别:

# REST FRAMEWORK 相关的配置
REST_FRAMEWORK = {
# 关于认证的全局配置
# "DEFAULT_AUTHENTICATION_CALSSES": ["app01.utils.auth.MyAuth",],
# "DEFAULT_PERMISSION_CLASSES" : ["app01.utils.permission.MyPermission"],
# "DEFAULT_THROTTLE_CLASSES" : ["app01.utils.throttle.MyThrottle",],
"DEFAULT_THROTTLE_CLASSES" : ["app01.utils.throttle.VisitThrottle",],
"DEFAULT_THROTTLE_RATES":{
"XXX":"5/m",
}
}
DRF 认证、权限、限制的更多相关文章
- (四) DRF认证, 权限, 节流
一.Token 认证的来龙去脉 摘要 Token 是在服务端产生的.如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端.前端可以在每次请求的时候带上 To ...
- 三 drf 认证,权限,限流,过滤,排序,分页,异常处理,接口文档,集xadmin的使用
因为接下来的功能中需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员. python manage.py createsuperuser 创建管理员以后,访问admin站点 ...
- DRF 认证 权限 视图 频率
认证组件 使用:写一个认证类,继承BaseAuthentication 在类中写authenticate方法,把request对象传入 能从request对象中取出用户携带的token根据token判 ...
- python 全栈开发,Day97(Token 认证的来龙去脉,DRF认证,DRF权限,DRF节流)
昨日内容回顾 1. 五个葫芦娃和三行代码 APIView(views.View) 1. 封装了Django的request - request.query_params --> 取URL中的参数 ...
- DRF之权限认证频率组件
概要 retrieve方法源码剖析 认证组件的使用方式及源码剖析 权限组件的使用方式及源码剖析 频率组件的使用方式及源码剖析 知识点复习回顾 Python逻辑运算 知识点复习回顾一:Python逻辑运 ...
- drf认证组件、权限组件、jwt认证、签发、jwt框架使用
目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...
- drf认证组件(介绍)、权限组件(介绍)、jwt认证、签发、jwt框架使用
目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...
- 实战-DRF快速写接口(认证权限频率)
实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestframework3.13 测试工具 Postma ...
- DRF的权限和频率
DRF的权限 权限组件源码 权限和频率以及版本认证都是在initial方法里初始化的 我们的权限类一定要有has_permission方法~否则就会抛出异常~~这也是框架给我提供的钩子~~ 在rest ...
随机推荐
- Go爬去以太坊的价格数据
package main import ( "encoding/json" "errors" "fmt" "io/ioutil&q ...
- Go学习之初出茅庐
在一个月黑风高的夜晚,机缘巧合与Go语言一面之缘,被她的简洁.灵活.高效所吸引,让我有深入学习的冲动,现在开始我的成长之路吧.
- jsp(待改)
##JSP 1.指令 作用:用于配置JSP页面,导入资源文件 *书写格式 <%@ 指令名称 属性1=值1,属性2=值2 ...%> *分类: *page :配置JSP页面的 #属性: c ...
- https://www.cnblogs.com/yudanqu/p/9467803.html
https://www.cnblogs.com/yudanqu/p/9467803.html
- ecs
第一章弹性计算服务ecs概述 1.什么是弹性计算服务ecs 2弹性计算服务ecs的特点 3.弹性计算服务ecs的应用场景 slb------ecs----ecs----------- rds ...
- Linux----------mysql进阶
目录 一.破解密码以及无密码登录 1.1 破解密码 1.2 无密码登录 1.3 定义不同的客户端 1.4 家目录下 二.视图 三.函数 3.1 系统函数 3.2 自定义函数 3.3 自定义函数中定义局 ...
- MySQL Hardware--网络测试
使用Ping测试丢包 ## ping测试 ## -c 100表示100次 ping -c 100 192.168.1.2 输出结果: ping -c 100 192.168.1.2 PING 192. ...
- C#中使用EntityFramework(EF)生成实体进行存储过程的调用
在EF中使用定义对象模型的方式调用一个存储过程,这个存储过程返回的是一组包含两列的值.(ProjectName,Count) 下面是存储过程: CREATE procedure [dbo].[Pro_ ...
- 错误界面 SQL2008备份集中的数据库备份与现有的数据库不同,错误号码:3154。
转载来源 https://blog.csdn.net/zaocha321/article/details/8466735 因为我也用这个方法成功了.所以记录下来 错误界面 SQL2005备份集中的数 ...
- centos 后台挂起运行python
用Xshell连接服务器运行python文件,当关闭终端或连接断开后相应的python文件也就不会继续运行了,要达到后台挂起运行就要使用 nohup 命令了. 用法如下: # -u 表示禁止缓存,将结 ...