04,认证、权限、频率

 

认证组件

Django原生的authentic组件为我们的用户注册与登录提供了认证功能,十分的简介与强大。同样DRF也为我们提供了认证组件,一起来看看DRF里面的认证组件是怎么为我们工作的!
models.py
# 定义一个用户表和一个保存用户Token的表 class UserInfo(models.Model): username = models.CharField(max_length=16) password = models.CharField(max_length=32) type = models.SmallIntegerField( choices=((1, '普通用户'), (2, 'VIP用户')), default=1 ) class Token(models.Model): user = models.OneToOneField(to='UserInfo') token_code = models.CharField(max_length=128)
15
1
# 定义一个用户表和一个保存用户Token的表
2
 
3
 
4
class UserInfo(models.Model):
5
    username = models.CharField(max_length=16)
6
    password = models.CharField(max_length=32)
7
    type = models.SmallIntegerField(
8
        choices=((1, '普通用户'), (2, 'VIP用户')),
9
        default=1
10
    )
11
 
12
 
13
class Token(models.Model):
14
    user = models.OneToOneField(to='UserInfo')
15
    token_code = models.CharField(max_length=128)
url
path('login/', views.LoginView.as_view()),
1
1
    path('login/', views.LoginView.as_view()),
views.py
# 视图主要处理用户名、密码是否正确,用户每一次请求都要带着专有token来! import hashlib, time from rest_framework.response import Response from rest_framework.views import APIView def get_random_token(username): """ 根据用户名和时间戳生成随机token :param username: :return: """ timestamp = str(time.time()) m = hashlib.md5(bytes(username, encoding="utf8")) m.update(bytes(timestamp, encoding="utf8")) return m.hexdigest() class LoginView(APIView): """ 校验用户名密码是否正确从而生成token的视图 """ def post(self, request): res = {"code": 0} print(request.data) username = request.data.get("username") password = request.data.get("password") user = models.UserInfo.objects.filter(username=username, password=password).first() if user: # 如果用户名密码正确 token = get_random_token(username) models.Token.objects.update_or_create(defaults={"token_code": token}, user=user) res["token"] = token else: res["code"] = 1 res["error"] = "用户名或密码错误" return Response(res)
38
1
# 视图主要处理用户名、密码是否正确,用户每一次请求都要带着专有token来!
2
import hashlib, time
3
from rest_framework.response import Response
4
from rest_framework.views import APIView
5
 
6
 
7
def get_random_token(username):
8
    """
9
    根据用户名和时间戳生成随机token
10
    :param username:
11
    :return:
12
    """
13
    timestamp = str(time.time())
14
    m = hashlib.md5(bytes(username, encoding="utf8"))
15
    m.update(bytes(timestamp, encoding="utf8"))
16
    return m.hexdigest()
17
 
18
 
19
class LoginView(APIView):
20
    """
21
    校验用户名密码是否正确从而生成token的视图
22
    """
23
    def post(self, request):
24
        res = {"code": 0}
25
        print(request.data)
26
        username = request.data.get("username")
27
        password = request.data.get("password")
28
 
29
        user = models.UserInfo.objects.filter(username=username, password=password).first()
30
        if user:
31
            # 如果用户名密码正确
32
            token = get_random_token(username)
33
            models.Token.objects.update_or_create(defaults={"token_code": token}, user=user)
34
            res["token"] = token
35
        else:
36
            res["code"] = 1
37
            res["error"] = "用户名或密码错误"
38
        return Response(res)
定义认证类model_serializer.py
# 这一步是要对着源码才能写出来 from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed class MyAuth(BaseAuthentication): def authenticate(self, request): if request.method in ["POST", "PUT", "DELETE"]: request_token = request.data.get("token", None) if not request_token: raise AuthenticationFailed('缺少token') token_obj = models.Token.objects.filter(token_code=request_token).first() if not token_obj: raise AuthenticationFailed('无效的token') return token_obj.user.username, None else: return None, None
18
1
# 这一步是要对着源码才能写出来
2
from rest_framework.authentication import BaseAuthentication
3
from rest_framework.exceptions import AuthenticationFailed
4
 
5
 
6
class MyAuth(BaseAuthentication):
7
    def authenticate(self, request):
8
        if request.method in ["POST", "PUT", "DELETE"]:
9
            request_token = request.data.get("token", None)
10
            if not request_token:
11
                raise AuthenticationFailed('缺少token')
12
            token_obj = models.Token.objects.filter(token_code=request_token).first()
13
            if not token_obj:
14
                raise AuthenticationFailed('无效的token')
15
            return token_obj.user.username, None
16
        else:
17
            return None, None
18
 
全局配置
# 在settings.py中配置 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ] }
4
1
# 在settings.py中配置
2
REST_FRAMEWORK = {
3
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ]
4
}

权限组件

只有vip才能看的内容
自定义权限类
# 自定义权限类 from rest_framework.permissions import BasePermission class MyPermission(BasePermission): message = 'VIP用户才能访问' def has_permission(self, request, view): """ 自定义权限只有VIP用户才能访问 """ # 因为在进行权限判断之前已经做了认证判断,所以这里可以直接拿到request.user if request.user and request.user.type == 2: # 如果是VIP用户 return True else: return False
15
1
# 自定义权限类
2
from rest_framework.permissions import BasePermission
3
 
4
class MyPermission(BasePermission):
5
    message = 'VIP用户才能访问'
6
 
7
    def has_permission(self, request, view):
8
        """
9
        自定义权限只有VIP用户才能访问
10
        """
11
        # 因为在进行权限判断之前已经做了认证判断,所以这里可以直接拿到request.user
12
        if request.user and request.user.type == 2:  # 如果是VIP用户
13
            return True
14
        else:
15
            return False
视图级别配置
class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer authentication_classes = [MyAuth, ] permission_classes = [MyPermission, ]
6
1
class CommentViewSet(ModelViewSet):
2
 
3
    queryset = models.Comment.objects.all()
4
    serializer_class = app01_serializers.CommentSerializer
5
    authentication_classes = [MyAuth, ]
6
    permission_classes = [MyPermission, ]
全局配置
REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ], "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ] }
4
1
REST_FRAMEWORK = {
2
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
3
    "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
4
}

频率组件

频率:限制用户访问网站的频率
自定义限制类
VISIT_RECORD = {} # 自定义限制 class MyThrottle(object): def __init__(self): self.history = None def allow_request(self, request, view): """ 自定义频率限制60秒内只能访问三次 """ # 获取用户IP ip = request.META.get("REMOTE_ADDR") timestamp = time.time() if ip not in VISIT_RECORD: VISIT_RECORD[ip] = [timestamp, ] return True history = VISIT_RECORD[ip] self.history = history history.insert(0, timestamp) while history and history[-1] < timestamp - 60: history.pop() if len(history) > 3: return False else: return True def wait(self): """ 限制时间还剩多少 """ timestamp = time.time() return 60 - (timestamp - self.history[-1])
33
1
VISIT_RECORD = {}
2
# 自定义限制
3
class MyThrottle(object):
4
 
5
    def __init__(self):
6
        self.history = None
7
 
8
    def allow_request(self, request, view):
9
        """
10
        自定义频率限制60秒内只能访问三次
11
        """
12
        # 获取用户IP
13
        ip = request.META.get("REMOTE_ADDR")
14
        timestamp = time.time()
15
        if ip not in VISIT_RECORD:
16
            VISIT_RECORD[ip] = [timestamp, ]
17
            return True
18
        history = VISIT_RECORD[ip]
19
        self.history = history
20
        history.insert(0, timestamp)
21
        while history and history[-1] < timestamp - 60:
22
            history.pop()
23
        if len(history) > 3:
24
            return False
25
        else:
26
            return True
27
 
28
    def wait(self):
29
        """
30
        限制时间还剩多少
31
        """
32
        timestamp = time.time()
33
        return 60 - (timestamp - self.history[-1])
视图级别配置
class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer throttle_classes = [MyThrottle, ]
x
1
class CommentViewSet(ModelViewSet):
2
 
3
    queryset = models.Comment.objects.all()
4
    serializer_class = app01_serializers.CommentSerializer
5
    throttle_classes = [MyThrottle, ]
全局配置
# 在settings.py中设置rest framework相关配置项 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ], "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ] "DEFAULT_THROTTLE_CLASSES": ["app01.utils.MyThrottle", ] }
1
# 在settings.py中设置rest framework相关配置项
2
REST_FRAMEWORK = {
3
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
4
    "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
5
    "DEFAULT_THROTTLE_CLASSES": ["app01.utils.MyThrottle", ]
6
}

认证组件的源码阅读

 

新构建的request里面的源码的user方法

 

源码走到了这里其实就已经需要我们自己来进行认证了。就可以对前端的请求进行认证,到底该怎么认证,还得继续往下走!

 

权限组件的源码阅读

相比较与认证组件,权限组件就更加的简洁了

频率组件的注意部分

转载于:https://www.cnblogs.com/pontoon/p/10217414.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jq获取input选取的文件名_tushare获取交易数据并可视化分析

获取数据是金融量化分析的第一步&#xff0c;找不到可靠、准确的数据&#xff0c;量化分析就无从谈起。随着信息技术的不断发展&#xff0c;数据获取渠道也越来越多&#xff0c;尤其是Python网络爬虫&#xff0c;近几年愈来愈火。然而&#xff0c;很多人毕竟精力有限&#xff0…

原来游戏技术行业最大的秘密竟然是...

欢迎大家前往腾讯云社区&#xff0c;获取更多腾讯海量技术实践干货哦~ 本文由腾讯游戏云发表于云社区专栏 本篇文章主要是分享游戏业务面临的安全风险场景&#xff0c;以及基于这些场景的特点&#xff0c;我们应该如何做好对应的防护。 【一、背景&#xff1a;游戏行业DDoS攻击…

指定Gradle构建属性

属性是用于轻松自定义Gradle构建和Gradle环境的宝贵工具。 我将在本文中演示一些用于指定Gradle构建中使用的属性的方法。 Gradle支持项目属性和系统属性 。 这篇文章中有趣的是两者之间的主要区别是如何访问它们。 通过常规Java / Groovy系统属性访问方法访问系统属性时&…

python数字转中文字符_Python实现中文数字转换为阿拉伯数字的方法示例

本文实例讲述了Python实现中文数字转换为阿拉伯数字的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a; 一、需求 今天写了三千二百行代码。 今天写了3200行代码。 两行意思相同&#xff0c;只是表达方式不太能够&#xff0c;统一掉。 二、原理 数字的特征是 数字 …

高级cmd攻击命令_一步一步学习DVWA渗透测试(Command Injection命令行注入)-第七次课...

各位小伙伴&#xff0c;今天我们继续学习Command Injection&#xff0c;翻译为中文就是命令行注入。是指通过提交恶意构造的参数破坏命令语句结构&#xff0c;从而达到执行恶意命令的目的。在OWASP TOP 10中一种存在注入漏洞&#xff0c;最常见的就是SQL和命令行注入。PHP开发的…

IDEA插件之 CodeGlance

在编辑代码最右侧&#xff0c;显示一块代码小地图 这款插件使用效果图如下&#xff0c;个人感觉还是有点用处&#xff0c;滚动条太小&#xff0c;有这个地图&#xff0c;拖动起来更加方便一点 原文地址:http://tengj.top/2017/02/22/idea1-1/转载于:https://www.cnblogs.com/al…

移动端图片上传方法

移动端图片上传方法 实现效果 文件下载 http://files.cnblogs.com/files/sntetwt/移动端图片上传.rar 实现步骤 一、隐藏<input type"file" id"file" name"Filedata" style"display:none;" accept"image/*" /> 二、…

c语言最大公约数和最小公倍数_五年级奥数课堂之七:公因数和公倍数

乘积尾0的个数公因数和公倍数的基本概念公因数的释义给定若干个整数&#xff0c;如果有一个(些)数是它们共同的因数&#xff0c;那么这个(些)数就叫做它们的公因数。而全部公因数中最大的那个&#xff0c;称为这些整数的最大公因数。公约数与公倍数相反&#xff0c;就是既是A的…

设计模式(五)--工厂模式汇总

LZ想把简单工厂模式、工厂方法模式和抽象工厂模式整理到一篇博文当中&#xff0c;由浅入深&#xff0c;应该能方便理解和记忆&#xff0c;话不多说&#xff0c;进入正题。 一、简单工厂模式 定义&#xff1a;从设计模式的类型上来说&#xff0c;简单工厂模式是属于创建型模式&a…

如何估算内存消耗?

这个故事可以追溯到至少十年之前&#xff0c;当时我第一次接触PHB时遇到一个问题&#xff1a;“在生产部署中&#xff0c;我们需要购买多大服务器”。 我们正在构建的新的&#xff0c;闪亮的系统距离生产开始还有9个月的时间&#xff0c;显然该公司已承诺提供包括硬件在内的整个…

python爬取b站403_Python如何爬取b站热门视频并导入Excel

代码如下 #encoding:utf-8 import requests from lxml import etree import xlwt import os # 爬取b站热门视频信息 def spider(): video_list [] url "https://www.bilibili.com/ranking?spm_id_from333.851.b_7072696d61727950616765546162.3" html requests.g…

使用调试器进行事后跟踪

我最近一直在使用的大多数调试器的好功能是能够在断点上记录信息。 这对理解代码而无需修改是非常有用的&#xff0c;它涉及字节码修改。 让我们考虑一下这种非常琐碎且效率低下的函数实现&#xff0c;以返回斐波那契数列中的第n个数字。 public class Fib {public long fib(…

链表排序c++代码_[链表面试算法](一) 链表的删除-相关题型总结(6题)

在数据结构的最高层抽象里&#xff0c;只有两种结构&#xff0c;数组和链表。这两种结构&#xff0c;是所有其他数据结构实现的基础。队列和栈&#xff0c;可以用链表和数组来实现。图&#xff0c;可以用邻接表和邻接矩阵来实现&#xff0c;其中&#xff0c;邻接表就是链表&…

c语言如何空格键返回主菜单,C语言中scanf函数与空格回车的用法说明

众所周知&#xff0c;C语言中的scanf函数的作用是从标准输入设备(通常是键盘)读取输入值&#xff0c;并存储到参数列表中指针所指向的内存单元。下面从几个方面说一下一些稍微细节的东西。下面的实验都在vc6.0中通过。1、scanf的返回值scanf通常返回的是成功赋值(从标准输入设备…

Linear_algebra_03_矩阵

1. 矩阵的线性运算&#xff1a; 2.1 矩阵的乘法&#xff1a;Xik * Ykj Zij 2.2 矩阵乘法性质&#xff1a; 3.1 矩阵的幂次方运算 3.2 矩阵转置的运算律 3.3 方阵运算 4 分块矩阵的运算 5. 矩阵的初等变换 5.1 单位矩阵I经过一次初等变换所得到的矩阵称为初等矩阵. 5.2 初等矩…

js转json工具_菜鸟丨Egert3D微信小游戏发布与Unity工具使用

本次教程将会为大家介绍Egret3D工具导出Unity场景对象的使用&#xff0c;以及发布微信小游戏流程。让大家对Egret 3D有更加熟悉的了解。需求工具&#xff1a;1、Unity场景导出插件&#xff1b;2、微信开发者工具。导出插件的使用一、打开需要导出的Unity场景&#xff0c;并且把…

OI杂记

从今天开始记录一下为数不多天的OI历程 8.25 上 今天举行了难得的五校联考&#xff0c;模拟noip&#xff0c;题目的解压密码竟然是$aKnoIp2o18$&#xff0c;对你没有看错&#xff01;&#xff01;&#xff01; 7:50老师&#xff1f;啊啊啊啊&#xff0c;收不到题目啊&#xff0…

Java,Steam控制器和我

您是否想过是否可以将现有的东西用于新的东西&#xff1f; 我看了一些所谓的“蒸汽控制器”&#xff08;从现在开始为SC&#xff09;的镜头&#xff0c;并看着我的游戏手柄。 问我自己是否有可能以类似蒸汽的方式使用它&#xff0c;我找到了一些Java库并创建了一个项目&#xf…

unknown column in field list_tf.feature_column的特征处理探究

1. 背景tf.estimator是tensorflow的一个高级API接口&#xff0c;它最大的特点在于兼容分布式和单机两种场景&#xff0c;工程师可以在同一套代码结构下即实现单机训练也可以实现分布式训练&#xff0c;正是因为这样的特点&#xff0c;目前包括阿里在内的很多公司都在使用这一接…

pytorch如何定义损失函数_对比PyTorch和TensorFlow的自动差异和动态模型

使用自定义模型类从头开始训练线性回归&#xff0c;比较PyTorch 1.x和TensorFlow 2.x之间的自动差异和动态模型子类化方法&#xff0c;这篇简短的文章重点介绍如何在PyTorch 1.x和TensorFlow 2.x中分别使用带有模块/模型API的动态子类化模型&#xff0c;以及这些框架在训练循环…