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. contos7搭建syslog服务端与客户端

    搭建中心服务端1,编辑文件/etc/rsyslog.conf,找到以下内容,将前面的#注释符合去除#$ModLoad imtcp#$InputTCPServerRun 514 2,在/etc/rsys ...

  2. vue + BMap实现常用地图

    实现功能: 缩放 自定义icon maker 多个覆盖点的点击事件 获取两点的距离 信息窗口的点击事件 <template> <div id="allmap" r ...

  3. 前端的UI框架

    iView 框架 使用场景 iView 主要适合大中型中后台产品,比如某产品的运营平台.数据监控平台.管理平台等,从工程配置.到样式布局,甚至后面规划的业务套件,是一整套的解决方案,所以它可能不太适合 ...

  4. 2019年4月zstu月赛A: 我不会做

    问题 A: 我不会做 时间限制: 1 Sec  内存限制: 128 MB 题目描述 众所周知,duxing201606就是plw. 然而已经9102年了,plw仍旧没有npy.plw非常难过,于是他打 ...

  5. java面试总躲不过的并发(一): 线程池ThreadPoolExecutor基础梳理

    本文核心:线程池ThreadPoolExecutor基础梳理 一.实现多线程的方式 1.继承Thread类,重写其run方法 2.实现Runnable接口,实现run方法 3.实现Callable接口 ...

  6. JMeter安装时Binarys与Source,tgz与zip如何选择?

    在 http://jmeter.apache.org/download_jmeter.cgi   或 http://jmeter.apache.org/   的 Download  版块下载 JMet ...

  7. JavaList列表的一些方法

    import java.util.ArrayList;import java.util.Iterator;import java.util.List; public class Test1 { pub ...

  8. flagr a/b 测试特性开关&&微服务动态配置工具

    flagr a/b 测试特性开关&&微服务动态配置工具 简单运行 docker docker run -it -p 18000:18000 checkr/flagr 运行界面 说明 参 ...

  9. DEV中的TreeList控件应用的一个小效果实现——个人总结

    我使用最多的DEV控件就是这个TreeList啦,当然用好它很不简单,如果用好它,能做出很精彩的树形层次结构图.TreeList控件很强大,以至于你看DEV自带的DEMO,也得浪费你很长时间应用.DE ...

  10. mysql入门学习笔记

    MySQL的登陆和退出 mysql -u 用户名 -p 密码 #登陆 quit #退出(exit or \q) 具体参数: 参数 描述 -D,--database=name 打开指定数据库 -deli ...