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 ...
随机推荐
- Java中switch对整型/字符型/字符串型具体实现细节
转自:http://www.hollischuang.com/archives/61 Java7中switch中支持的数据类型有: byte short int char String类型 其实swi ...
- sping配置头文件
spring配置文件头部xmlns配置精髓 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <beans xmlns="http://www.s ...
- adb 安装安卓包
1.搭建安卓环境,或者下载安装ADB工具 2.adb version检查是否安装成功 3.用数据线连上手机,并在手机中打开USB调试模式,使用adb devices 查看链接的设备 这样表示成功连接上 ...
- PHP 多维数组排序 函数怎么保持数字键不被重新索引
/** * 根据数组中的某个键值大小进行排序,仅支持二维数组 * * @param array $array 排序数组 * @param string $key 键值 * @param bool $a ...
- NSURLConnectionDataDelegate
#pragma mark-NSURLConnectionDataDelegate //收到回应 - (void)connection:(NSURLConnection *)connection did ...
- Java基础知识学习思维导图
- Git 几个常用操作
git init -- 初始化仓库, git clone -- 从远端克隆仓库到本地 git status -- 查看git仓库的状态 git log ...
- 解决ubuntu输入正确用户密码重新跳到无法登录
解决方法:我们需要将.Xauthority的拥有者改为登陆用户(或者干脆将.Xauthority删除,此法转自网上,本人未验证)开机后在登陆界面按下shift + ctrl + F1进入tty命令行终 ...
- 【druid 】数据库连接池
一.数据库连接池架构 二.数据库连接池的过滤器 spi的思想,加载配置文件的Filter druid.filters.default=com.alibaba.druid.filter.stat.Sta ...
- 6_7_8_10html-css
Ps: 1.标准流 2.浮动 3.定位 CCS重点 <!DOCTYPE html> <html lang="en"> <head> & ...