DRF三大认证

DRF三大认证

目录

  • DRF三大认证
    • 身份认证
      • 自定义认证类
    • 权限控制
      • 自定义权限类
    • 限制频率
      • 自定义频率类

身份认证

源码分析:

APIView–dispatch–initial()–perform_authentication()

def perform_authentication(self, request):
    """
    Perform authentication on the incoming request.

    Note that if you override this and simply 'pass', then authentication
    will instead be performed lazily, the first time either
    `request.user` or `request.auth` is accessed.
    """
    # 调用Request的user属性
    request.user
def _authenticate(self):
    # 遍历认证器对request请求进行验证
    """
    Attempt to authenticate the request using each authentication instance
    in turn.
    """
    # self.authenticators:Request的认证器组成的list
    for authenticator in self.authenticators:
        try:
            *****重点*****
            # 如果认证成功则返回由user和认证信息组成的元组
            user_auth_tuple = authenticator.authenticate(self)
        except exceptions.APIException:
            # 认证失败则抛出异常
            self._not_authenticated()
            raise
		
        # 对认证成功的数据进行处理
        if user_auth_tuple is not None:
            # 将认证器返回给self._authenticator
            self._authenticator = authenticator
            # 对认证请求的信息分别赋值给:登录用户、登录认证
            self.user, self.auth = user_auth_tuple
            return
	# 如果未得到认证则调用该方法:设置未经身份验证的请求的身份验证器
    self._not_authenticated()
def _not_authenticated(self):
    """
    Set authenticator, user & authtoken representing an unauthenticated request.

    Defaults are None, AnonymousUser & None.
    """
    
    # 验证器为None,表示未经验证
    self._authenticator = None

    # 判断用户是否被认证过
    if api_settings.UNAUTHENTICATED_USER:
        # 将user设置为匿名用户
        self.user = api_settings.UNAUTHENTICATED_USER()
    else:
        # 将user设置为空
        self.user = None

    # 判断token是否被认证过,是则将auth设为未经验证的令牌,否则为空
    if api_settings.UNAUTHENTICATED_TOKEN:
        self.auth = api_settings.UNAUTHENTICATED_TOKEN()
    else:
        self.auth = None

自定义认证类

  • 继承BaseAuthentication

  • 重写**authenticate(self, request)**方法

  • 认证规则基于的条件:

    • 没有认证信息返回None(游客)
    • 有认证信息认证失败抛异常(非法用户)
    • 有认证信息认证成功返回用户与认证信息的元素(合法用户)
  • 完成视图类的全局(settings.py)或局部(指定的视图类)配置

# MyValidate.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

from user.models import UserToken


class Authentication(BaseAuthentication):
    def authenticate(self, request):
        # 获取浏览器token
        token = request.META.get('HTTP_TOKEN')
        print(token)
        # UserToken表中校验token是否存在
        user_token = UserToken.objects.filter(token=token).first()
        if user_token:
            # 返回user和token
            user = user_token.user
            return user, token
        else:
            raise AuthenticationFailed('请登录')

局部认证

# views.py
from app.MyValidate import Authentication

class userinfo(APIView):
    authentication_classes = [MyAuthentication]

全局认证

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'app.MyValidate.Authentication'
    ],
}

权限控制

源码分析:

APIView–dispatch–initial()–check_permissions()

def check_permissions(self, request):
    # 检查请求是否有权限,没有则抛出异常
    """
    Check if the request should be permitted.
    Raises an appropriate exception if the request is not permitted.
    """
    
    # 遍历权限对象列表依次进行权限校验
    for permission in self.get_permissions():
        if not permission.has_permission(request, self):
            # has_permission:用来做权限认证的方法
            # 参数:权限对象self、request、视图类对象
            # 返回值:有权返回True 无权则False
            self.permission_denied(
                request,
                message=getattr(permission, 'message', None),
                code=getattr(permission, 'code', None)
            )
def get_permissions(self):
    # 实例化并返回此视图所需的权限列表
    """
    Instantiates and returns the list of permissions that this view requires.
    """
    return [permission() for permission in self.permission_classes]
def has_object_permission(self, request, view, obj):
    """
    Return `True` if permission is granted, `False` otherwise.
    """
    return True

自定义权限类

  • 继承BasePermission

  • 重写**has_permission(request, self)**方法

  • 认证规则基于的条件:

    • 没有认证信息返回None(游客)
    • 有认证信息认证失败抛异常(非法用户)
    • 有认证信息认证成功返回用户与认证信息的元素(合法用户)
  • 完成视图类的全局(settings.py)或局部(指定的视图类)配置

# MyValidate.py
class Permission(BasePermission):
    # 只有超级用户有权限
    def has_permission(self, request, view):
        level = UserInfo.objects.get(username=request.user).level
        if level < 3:
            return False
        return True
# models.py
class UserInfo(AbstractUser):
    level = models.IntegerField(choices=[(1, '普通用户'), (2, '普通管理员'), (3, '超级管理员')], default=1)

局部认证

# views.py
from app.MyValidate import Permission

class book(APIView):
    permission_classes = [Permission]

全局认证

# 权限类配置
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'app.MyValidate.Permission'
    ],
}

限制频率

源码分析:

APIView–dispatch–initial()–check_throttles()

def check_throttles(self, request):
    """
    Check if request should be throttled.
    Raises an appropriate exception if the request is throttled.
    """
    throttle_durations = []
    # 遍历配置的频率认证类,初始化得到一个个频率认证类对象(会调用频率认证类的 __init__() 方法)
    for throttle in self.get_throttles():
        # 频率认证类对象调用 allow_request 方法,判断是否限次(没有限次可访问,限次不可访问)
        if not throttle.allow_request(request, self):
            # 频率认证类对象在限次后,调用 wait 方法,获取还需等待多长时间可以进行下一次访问
            throttle_durations.append(throttle.wait())

    if throttle_durations:
        # Filter out `None` values which may happen in case of config / rate
        # changes, see #1438
        durations = [
            duration for duration in throttle_durations
            if duration is not None
        ]

        duration = max(durations, default=None)
        self.throttled(request, duration)
# from rest_framework.throttling import SimpleRateThrottle

class SimpleRateThrottle(BaseThrottle):
    """
    A simple cache implementation, that only requires `.get_cache_key()`
    to be overridden.

    The rate (requests / seconds) is set by a `rate` attribute on the Throttle
    class.  The attribute is a string of the form 'number_of_requests/period'.

    Period should be one of: ('s', 'sec', 'm', 'min', 'h', 'hour', 'd', 'day')

    Previous request information used for throttling is stored in the cache.
    """
    cache = default_cache
    timer = time.time
    cache_format = 'throttle_%(scope)s_%(ident)s'
    scope = None
    THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES

    def __init__(self):
        if not getattr(self, 'rate', None):
            self.rate = self.get_rate()
        self.num_requests, self.duration = self.parse_rate(self.rate)

    def get_cache_key(self, request, view):
        # 需要我们重写的方法 
        """
        Should return a unique cache-key which can be used for throttling.
        Must be overridden.

        May return `None` if the request should not be throttled.
        """
        raise NotImplementedError('.get_cache_key() must be overridden')

自定义频率类

  • 继承SimpleRateThrottle
  • 重写get_cache_key()方法
  • 设置一个rate属性,意为访问频率限制,如'5/s'
# MyValidate.py
from rest_framework.throttling import SimpleRateThrottle

class CommonThrottle(SimpleRateThrottle):
    rate = '3/m'

    def get_cache_key(self, request, view):
        # 返回什么,就会以什么做限制, ip地址限制;用户id
        return request.META.get('REMOTE_ADDR')

局部限制

# views.py
from app.MyValidate import CommonThrottle

class book(APIView):
    throttle_classes = [CommonThrottle]

全局限制

REST_FRAMEWORK = {

    'DEFAULT_THROTTLE_CLASSES': ['app.MyValidate.CommonThrottle'],
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用API有效率地管理Dynadot域名,锁定账户中的域名

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

Zynq7000系列中的时钟管理

PS&#xff08;处理系统&#xff09;时钟子系统生成的所有时钟都源自三个可编程PLL&#xff08;锁相环&#xff09;中的一个&#xff1a;CPU、DDR和I/O。时钟子系统的主要组件如图25-1所示。 在正常工作期间&#xff0c;PLL被启用&#xff0c;并由PS_CLK时钟引脚驱动。在启用P…

6.6Python之集合的基本语法和特性

集合&#xff08;Set&#xff09;是Python中的一种无序、不重复的数据结构。集合是由一组元素组成的&#xff0c;这些元素必须是不可变数据类型&#xff0c;但在集合中每个元素都是唯一的&#xff0c;即集合中不存在重复的元素。 集合的基本语法&#xff1a; 1、元素值必须是…

24卫生高级职称报名时间汇总⏰报名全流程

⏰卫生高级职称&#xff08;网上报名&#xff09;时间汇总 ✔️陕西&#xff1a;4月23日-5月24日 ✔️上海&#xff1a;4月23日-5月24日 ✔️重庆&#xff1a;4月23日—5月24日 ✔️黑龙江&#xff1a;4月23日-5月24日 ✔️浙江&#xff1a;4月23日-5月24日 ✔️云南&#xff1…

面试自救指南:女生如何巧答私密问题

在面试过程中&#xff0c;女性应聘者可能会遇到一些私人问题&#xff0c;这些问题可能涉及婚姻、家庭、生育等方面。面对这些问题&#xff0c;如何回答才能既保持真实又不失礼节呢&#xff1f; 当遇到关于婚姻状况的问题时&#xff0c;您可以选择回答&#xff1a;“我目前的婚姻…

【Python深度学习系列】网格搜索神经网络超参数:权重初始化方法(案例+源码)

这是我的第262篇原创文章。 一、引言 在深度学习中&#xff0c;超参数是指在训练模型时需要手动设置的参数&#xff0c;它们通常不能通过训练数据自动学习得到。超参数的选择对于模型的性能至关重要&#xff0c;因此在进行深度学习实验时&#xff0c;超参数调优通常是一个重要的…

2024全新快递平台系统独立版小程序源码|带cps推广营销流量主+前端

本文来自&#xff1a;2024全新快递平台系统独立版小程序源码|带cps推广营销流量主前端 - 源码1688​​​​​ 应用介绍 快递代发快递代寄寄件小程序可以对接易达云洋一级总代快递小程序&#xff0c;接入云洋/易达物流接口&#xff0c;支持选择快递公司&#xff0c;三通一达&am…

【leetcode面试经典150题】57. 环形链表(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

电动车违停智能监测摄像机

电动车的普及带来了便利&#xff0c;但也衍生了一些问题&#xff0c;其中最常见的之一就是电动车的违停。电动车的违停不仅会影响交通秩序&#xff0c;还可能对周围环境和行人安全造成影响。为了监测和管理电动车的违停情况&#xff0c;可以使用电动车违停智能监测摄像机。这种…

退市危机袭来,环保行业能否逆境崛起?|中联环保圈

近年来&#xff0c;环保行业风波持续不断&#xff0c;众多环保大公司风险频出。博天环境的退市危机令人感慨&#xff0c;深圳星源因涉嫌信息披露违法违规而被警告退市&#xff0c;更是引发业界震动。 最近三年&#xff0c;证监会办理的上市公司信息披露违法案件多达 397 件&…

Linux内核之virt_to_page实现与用法实例(五十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Python 使用 pip 安装 matplotlib 模块(精华版)

pip 安装 matplotlib 模块 1.使用pip安装matplotlib(五步实现):2.使用下载的matplotlib画图: 1.使用pip安装matplotlib(五步实现): 长话短说&#xff1a;本人下载 matplotlib 花了大概三个半小时屡屡碰壁&#xff0c;险些暴走。为了不让新来的小伙伴走我的弯路&#xff0c;特意…

IPAguard--iOS代码混淆工具(免费)

IPAguard是一款为iOS开发者设计的代码混淆工具&#xff0c;旨在为开发者提供方便制作和分析马甲包的解决方案。通过高效的匹配算法&#xff0c;IPAguard可以在保证代码混淆的同时&#xff0c;保证编译后的代码质量&#xff0c;减少了因混淆引起的bug&#xff0c;使得开发者能够…

写后端项目的分页查询时,解决分页不更新

写基于VueSpringBoot项目&#xff0c;实现分页查询功能时&#xff0c;改完代码后&#xff0c;发现页数不更新&#xff1a; 更改处如下&#xff1a; 显示如图&#xff1a; 发现页数没有变化&#xff0c;两条数据还是显示在同一页&#xff0c;而且每页都10条。且重启项目也没有更…

代码随想录算法训练营第一天 | 704. 二分查找 | 27. 移除元素

704. 二分查找 int search(int* nums, int numsSize, int target) {int left 0, right numsSize, mid;while (left < right) {mid left (right -left) / 2;if (nums[mid] < target) {left mid 1;} else if (nums[mid] > target) {right mid;} else {return mid…

民兵档案管理系统-退伍军人档案管理全流程追踪

民兵档案管理系统&#xff08;智档案DW-S403&#xff09;是依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 RFID档案管理系统是以先进的RFID技术为基础&#xff0c;结合数据库技术、…

压缩感知的概述梳理(1)

参考文献 An efficient visually meaningful image compression and encryption scheme based on compressive sensing and dynamic LSB embedding 基本内容 基本关系梳理 压缩感知核心元素 信号 x 长度&#xff1a;N动态稀疏或可用变换表示&#xff1a;x &#x1d74d;s …

AI实践与学习4_大模型之检索增强生成RAG实践

背景 针对AI解题业务场景&#xff0c;靠着ToT、CoT等提示词规则去引导模型的输出答案&#xff0c;一定程度相比Zero-shot解答质量更高&#xff08;正确率、格式&#xff09;等。但是针对某些测试CASE&#xff0c;LLM仍然不能输出期望的正确结果&#xff0c;将AI解题应用生产仍…

「不羁联盟/XDefiant」4月20号开启服务器测试,游戏预下载安装教程

XDefiant》开启Alpha测试&#xff0c;这是一款免费游玩的快节奏 FPS 竞技游戏&#xff0c;可选择特色阵营&#xff0c;搭配个性化的装备&#xff0c;体验 6v6 对抗或是线性游戏模式。高品质射击竞技端游XDefiant以6v6双边对抗为核心&#xff0c;对局模式分为区域与线性两大类&a…

LeetCode108:讲有序数组转换为平衡二叉搜索树

题目描述 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡二叉搜索树。 代码 class Solution { public:TreeNode* traversal(vector<int>& nums, int left, int right) {if (left > right) return nullptr;int …
最新文章