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 认证、权限、限制的更多相关文章

  1. (四) DRF认证, 权限, 节流

    一.Token 认证的来龙去脉 摘要 Token 是在服务端产生的.如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端.前端可以在每次请求的时候带上 To ...

  2. 三 drf 认证,权限,限流,过滤,排序,分页,异常处理,接口文档,集xadmin的使用

    因为接下来的功能中需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员. python manage.py createsuperuser 创建管理员以后,访问admin站点 ...

  3. DRF 认证 权限 视图 频率

    认证组件 使用:写一个认证类,继承BaseAuthentication 在类中写authenticate方法,把request对象传入 能从request对象中取出用户携带的token根据token判 ...

  4. python 全栈开发,Day97(Token 认证的来龙去脉,DRF认证,DRF权限,DRF节流)

    昨日内容回顾 1. 五个葫芦娃和三行代码 APIView(views.View) 1. 封装了Django的request - request.query_params --> 取URL中的参数 ...

  5. DRF之权限认证频率组件

    概要 retrieve方法源码剖析 认证组件的使用方式及源码剖析 权限组件的使用方式及源码剖析 频率组件的使用方式及源码剖析 知识点复习回顾 Python逻辑运算 知识点复习回顾一:Python逻辑运 ...

  6. drf认证组件、权限组件、jwt认证、签发、jwt框架使用

    目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...

  7. drf认证组件(介绍)、权限组件(介绍)、jwt认证、签发、jwt框架使用

    目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...

  8. 实战-DRF快速写接口(认证权限频率)

    实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestframework3.13 测试工具 Postma ...

  9. DRF的权限和频率

    DRF的权限 权限组件源码 权限和频率以及版本认证都是在initial方法里初始化的 我们的权限类一定要有has_permission方法~否则就会抛出异常~~这也是框架给我提供的钩子~~ 在rest ...

随机推荐

  1. org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Cannot open con

    org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session f ...

  2. 在LINUX(Ubuntu 18.04.x、CentOS)下配置MySQL8.0.x

    安装教程:Installing MySQL on Unix/Linux Using Generic Binaries MySQL下载链接:https://dev.mysql.com/downloads ...

  3. css animate

    AniX https://a-jie.github.io/AniX/

  4. js 计算浮点数

    JS的浮点计算 最近遇到了数值计算的时候,计算结果出现了类似于199.9999999999999999999的情况,但是被用来计算的两个数值都只是两位数. 就像这样      --------> ...

  5. 多线程——C++

    线程: 先说进程,进程是应用程序的执行实例,每个进程拥有其私有的虚拟地址空间.代码.数据和其它系统资源组成.进程在运行时创建的资源随着进程的终止而死亡. 而线程是一个独立的执行流,是进程内部的一个独立 ...

  6. PTA——出现次数最多的数

    PTA 7-58 求整数序列中出现次数最多的数 #include<stdio.h> #define N 1000 int main() { ,flag; ]; scanf("%d ...

  7. AssetBundle打包-----BuildPipeline的应用

    打包思路:确定要打包资源的路径.和打包的输出路径(一般为S路径),把存放资源的路径使用递归进行遍历,获取所有资源,文件类型的资源可以通过File拷贝或IO写到输出路径,其他资源的打包通过AssetBu ...

  8. openpyxl工具总结

    1.openpyxl使用 涉及到单元格合并.赋值 ''' .格式转换 raw_data create_data boolean Bool uint8 UInt8 int8 Int8 uint16 UI ...

  9. Java I/O输入输出流

    IO流的复习总结 ------注:蓝色背景段落是例子:红色背景的字段IO流的功能类. 编码问题 String s = "威力锅ABC";  //utf-8编码中文占用三个字节,英文 ...

  10. JS ajax请求参数格式( formData 、serialize)

    $("#importBtn").click(function(){ if($("#conId").val() == ""){ alert(& ...