DRF 三大认证

2024-04-23 03:12
文章标签 认证 三大 drf

本文主要是介绍DRF 三大认证,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

三大认证使用

【0】准备

(1)APIView源码回顾

  • APIView不用csrf验证了
  • APIView的request方法不在是以前的request方法,有了很多好用的新方法
  • APIView内部还分别进行了了用户、权限、频率的验证
  • 三大认证之后才执行的视图层的方法

image-20240417144150517

(2)模型表创建

from django.db import models# 图书表
class Book(models.Model):name = models.CharField(max_length=64, verbose_name="书名")price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="价格")publish_name = models.CharField(max_length=64, verbose_name="出版社名字")# 用户表
class User(models.Model):name = models.CharField(max_length=64, verbose_name='用户名')password = models.CharField(max_length=64, verbose_name='密码')role = models.IntegerField(choices=((0, "Admin"), (1, 'Normal')), verbose_name='用户名')# 用户token表
class UserToken(models.Model):token = models.CharField(max_length=64, verbose_name='token')user = models.OneToOneField(to=User, on_delete=models.CASCADE, verbose_name="关联用户表")

【1】认证组件

(1)简介

  • 三大认证之首,只有通过这个认证才会进行两外两个认证
  • 认证组件用于确定请求是来自谁。例如,它可以检查一个请求是否附带了一个有效的用户会话token,从而识别出请求的用户。

(2)使用方法

  1. 编写一个继承BaseAuthentication的类

    • from rest_framework.authentication import BaseAuthentication
  2. 重写authenticate方法

    • 可以在BaseAuthentication类中看到authenticate() must be overridden的提示,提示我们要重写
  3. 重写方法中进行特殊内容的判断(这里是token)

    • token是后端开发者对前端传输数据进行要求的,可以指定内容,可以指定格式,由于无论什么请求方式,都会发送请求头,所以可以指定数据放在请求头中
    • 请求通过,直接返回用户对象和token
    • 请求失败,抛异常AuthenticationFailed
      • from rest_framework.exceptions import AuthenticationFailed
      • 例如:raise AuthenticationFailed("请先登录再重试。")
  4. 配置使用

    1. 局部使用

      • 在试图内中添加authentication_classes = [自定义认证类列表],这是个列表,所以说明可以添加多个认证类
    2. 全局使用

      • 直接去drfsetting配置文件中找

      • REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['字符串形式导入自定义认证类',],
        }
        
    3. 局部禁用

      • 再进行全局配置即所有视图类都需要登录认证以后
      • 根据就近优先原则,只要将当前的视图类中authentication_classes 置空就可以取消认证,即局部禁用

(3)示例

  • 路由层:使用继承ViewSetMixin的视图类,所以直接自动生成路由
from django.urls import path, include
from .views import UserAPIView
from rest_framework.routers import SimpleRouterrouter = SimpleRouter()
router.register(prefix='user', viewset=UserAPIView, basename='user')
router.register(prefix='book', viewset=BookAPIView, basename='book')
urlpatterns = [path('', include(router.urls))
]
  • 视图函数登录功能
    • 注册就直接再数据库添加了
    • update_or_create(defaults={'token': token}, user=user_obj)讲解
      • defaults参数是一个字典,需要添加的所有字段信息(除了后面的那个字段)
      • 这里的字段是user,即根据user进行判断,这个数据是已经添加过的还是新的,如果是新的那么就是创建,如果是旧的数据,那么就进行更新
# 登录功能
import uuid
from rest_framework.viewsets import ViewSet
from .models import User, UserToken
from rest_framework.response import Response
from rest_framework.decorators import actionclass UserAPIView(ViewSet):@action(methods=['post'], detail=False)def login(self, request):username = request.data.get('username')password = request.data.get('password')user_obj = User.objects.filter(username=username, password=password).first()if user_obj:token = uuid.uuid4()UserToken.objects.update_or_create(defaults={'token': token}, user=user_obj)return Response({"code": 100, "msg": "登录成功", "token": token})return Response({"code": 101, "msg": "登录失败,用户名或密码错误"})
# 书籍查询所有,添加单本
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin, CreateModelMixin
from .serializer import BookModelSerializer
from .authentication import LoginAuthclass BookAPIView(GenericViewSet, ListModelMixin, CreateModelMixin):queryset = Book.objects.all()serializer_class = BookModelSerializer# 认证类authentication_classes = [LoginAuth]# 序列化类
from rest_framework.serializers import ModelSerializer
from .models import Bookclass BookModelSerializer(ModelSerializer):class Meta:model = Bookfields = '__all__'
  • 认证类编写
    • 需要注意的是,前端的数据是放在请求头中的token,再后端需要加上HTTP_大写变量取值
    • 最后成功返回usertoken
    • 不成功抛出异常AuthenticationFailed
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from .models import UserTokenclass LoginAuth(BaseAuthentication):def authenticate(self, request):token = request.META.get("HTTP_TOKEN")token_obj = UserToken.objects.filter(token=token).first()if token_obj:return token_obj.user, tokenraise AuthenticationFailed("请先登录再重试。")
  • 试图函数测试:书籍信息查询功能
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .serializer import BookModelSerializer
from .authentication import LoginAuthclass BookAPIView(GenericViewSet, ListModelMixin):queryset = Book.objects.all()serializer_class = BookModelSerializerauthentication_classes = [LoginAuth]
  • 不登陆测试

image-20240417154617946

  • 登录后添加token测试

image-20240417155235666

【2】权限组件

(1)简介

  • 三大认证的第二个,到这里说明已经通过了认证组件
  • 权限组件用于确定已认证的用户是否有权限执行某个操作。例如,一个API视图可能只允许特定的用户组或具有特定权限的用户访问。

(2)使用方法

  1. 编写一个继承BasePermission的类

    • from rest_framework.permissions import BasePermission
  2. 重写has_permission方法

    • 根据自定义规则,通过返回True,失败返回False
    • 验证不通过自定义返回信息f方法,抛出异常AuthenticationFailed
      • from rest_framework.exceptions import PermissionDenied
      • 例如:raise PermissionDenied(f'你是【{role_info}】,没有权限执行当前操作。')
  3. 配置使用

    1. 局部使用

      • 在试图内中添加permission_classes = [自定义权限类列表],这是个列表,所以说明可以添加多个权限类
    2. 全局使用

      • 直接去drfsetting配置文件中找

      • REST_FRAMEWORK = {'DEFAULT_PERMISSION_CLASSES': ['字符串形式导入自定义认证类',],
        }
        
    3. 局部禁用

      • 再进行全局配置即所有视图类都需权限认证以后
      • 根据就近优先原则,只要将当前的视图类中permission_classes 置空就可以取消权限认证,即局部禁用

(3)示例

  • 注意:前面必须要有认证类通过认证才可以即一定要有authentication_classes,因为这里的权限认证是从登录后的信息拿取权限的内容

  • 权限类编写

    • 根据自定义规则进项权限检查
    • 最后成功返回True
    • 不成功抛出异常PermissionDenied
    • 由于User表是自定义的没有继承django的用户表,所以是没有is_authenticated方法,需要再模型表中自定义,返回个True即可,表示是这个表创建的
# 权限
from rest_framework.permissions import BasePermission
from rest_framework.exceptions import PermissionDeniedclass AdminPermission(BasePermission):def has_permission(self, request, view):# 检查是否登录if request.user.is_authenticated:# 检查权限只有管理员才可以if request.user.role == 0:return Truerole_info = request.user.get_role_display()raise PermissionDenied(f'你是【{role_info}】,没有权限执行当前操作。')raise PermissionDenied(f'请先登录执行当前操作。')# 模型表
class User(models.Model):username = models.CharField(max_length=64, verbose_name='用户名')password = models.CharField(max_length=64, verbose_name='密码')role = models.IntegerField(choices=((0, "Admin"), (1, 'Normal')), verbose_name='用户名')@propertydef is_authenticated(self):return True
  • 视图函数测试:
    • 在添加一个书籍对单本图书的视图函数,使用路由注册视图集时,每个视图集通常应该对应一个特定的 URL 前缀,以避免冲突。
# 路由层
from django.urls import path, include
from .views import UserAPIView, BookAPIView, BookOneAPIView
from rest_framework.routers import SimpleRouterrouter = SimpleRouter()
router.register(prefix='user', viewset=UserAPIView, basename='user')
router.register(prefix='books', viewset=BookAPIView, basename='books')
router.register(prefix='book', viewset=BookOneAPIView, basename='book_one')
urlpatterns = [path('', include(router.urls))
]# 视图层
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, \DestroyModelMixin
from .serializer import BookModelSerializer
from .authentication import LoginAuth
from .permission import AdminPermissionclass BookAPIView(GenericViewSet, ListModelMixin, RetrieveModelMixin):queryset = Book.objects.all()serializer_class = BookModelSerializerauthentication_classes = [LoginAuth]permission_classes = []class BookOneAPIView(GenericViewSet, CreateModelMixin, UpdateModelMixin, DestroyModelMixin):queryset = Book.objects.all()serializer_class = BookModelSerializerauthentication_classes = [LoginAuth]permission_classes = [AdminPermission]
  • 普通用户测试

image-20240417185503126

  • 管理员测试

image-20240417185547653

【3】频率组件

(1)简介

  • 三大认证的最后一个,到这里说明已经通过了认证和权限组件
  • 权限组件用于确定已认证的用户是否有权限执行某个操作。例如,一个API视图可能只允许特定的用户组或具有特定权限的用户访问。

(2)SimpleRateThrottle使用方法

  1. 编写一个继承SimpleRateThrottle的类

    • from rest_framework.throttlingimport SimpleRateThrottle
  2. 重写get_cache_key方法

    • 可以在SimpleRateThrottle类中看到get_cache_key() must be overridden的提示,提示我们要重写
    • 在类属性中定义一个rate属性
      • 参数形式为:3/m,这里表示一分钟内最多访问三次
      • 所以第一个参数是次数,/后面的是单位,s是秒,m是分钟,h是小时,实际上写全称也可以,只和首字母有关,源码导致
    • 这个方法需要返会限制频率的唯一标识
      • 返回request.META.get('REMOTE_ADDR')表示IP
  3. 配置使用

    1. 局部使用

      • 在试图内中添加throttle_classes= [自定频率类列表],这是个列表,所以说明可以添加多个频率类
    2. 全局使用

      • 直接去drfsetting配置文件中找

      • REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ['字符串形式导入自定义频率类',],
        }
        
    3. 局部禁用

      • 再进行全局配置即所有视图类都限制频率以后
      • 根据就近优先原则,只要将当前的视图类中throttle_classes 置空就可以取消频率限制,即局部禁用

(3)示例

  • 频率类编写
    • 重写get_cache_key方法,返回IP
    • 添加类属性rate
from rest_framework.throttling import BaseThrottle, SimpleRateThrottleclass CommonThrottle(SimpleRateThrottle):rate = '3/m'def get_cache_key(self, request, view):return request.META.get('REMOTE_ADDR')
  • 视图函数测试:
class BookAPIView(ReadOnlyModelViewSet):queryset = Book.objects.all()serializer_class = BookModelSerializerauthentication_classes = [LoginAuth]permission_classes = []throttle_classes = [CommonThrottle]

image-20240417191537786

(4)BaseThrottle使用方法

  • SimpleRateThrottle的使用方法差不多,不过要麻烦很多,几乎要完全自定义,需要重写allow_request方法

  • 补充一点:

    • 正常来说,通过返回True,不通过返回False
    • 但是不通过可以自定义返回信息,使用Throttled实例化一个信息,并抛出这个异常。
      • from rest_framework.exceptions import Throttled
from rest_framework.throttling import BaseThrottle
from rest_framework.exceptions import Throttledclass ComplexThrottle(BaseThrottle):login_dict = {}  # 登录信息字典frequency = 3  # 时间内访问次数interval = 10  # 时间间隔 sdef allow_request(self, request, view):print(self.login_dict)now_ip = request.META.get('REMOTE_ADDR')now_time = time.time()# 是否是新用户if now_ip not in self.login_dict.keys():self.login_dict[now_ip] = [now_time]return Trueelse:# 时间间隔dif = now_time - self.login_dict.get(now_ip)[0]# 时间间隔大于指定间隔if dif > self.interval:self.login_dict.get(now_ip).pop(0)self.login_dict.get(now_ip).append(now_time)return True# 存储超过指定数量不在添加elif len(self.login_dict.get(now_ip)) >= self.frequency:# 自定义返回内容raise Throttled(detail={'msg': f"访问频率过高,请等待{self.interval - int(dif)}秒后再试。"})# 最后说明:在时间间隔内,且有位置可以添加else:self.login_dict[now_ip].append(now_time)return True

这篇关于DRF 三大认证的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/927625

相关文章

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

【Shiro】Shiro 的学习教程(二)之认证、授权源码分析

目录 1、背景2、相关类图3、解析3.1、加载、解析阶段3.2、认证阶段3.3、授权阶段 1、背景 继上节代码,通过 debug 进行 shiro 源码分析。 2、相关类图 debug 之前,先了解下一些类的结构图: ①:SecurityManager:安全管理器 DefaultSecurityManager: RememberMeManager:实现【记住我】功能

OpenStack离线Train版安装系列—3控制节点-Keystone认证服务组件

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack Victoria版——3.控制节点-Keystone认证服务组件

3.控制节点-Keystone认证服务组件 更多步骤:OpenStack Victoria版安装部署系列教程 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版 离线安装部署系列教程(全) OpenStack Train版 离线安装部署系列教程(全) 欢迎留言沟通,共同进步。 文章目录 创建key

JVM、JRE和 JDK:理解Java开发的三大核心组件

Java是一门跨平台的编程语言,它的成功离不开背后强大的运行环境与开发工具的支持。在Java的生态中,JVM(Java虚拟机)、JRE(Java运行时环境)和JDK(Java开发工具包)是三个至关重要的核心组件。本文将探讨JVM、JDK和JRE的区别,帮助你更好地理解Java的运行机制。 1. JVM:Java虚拟机(Java Virtual Machine) 什么是JVM? JVM,即

接口自动化三大经典难题

目录 一、接口项目不生成token怎么解决关联问题 1. Session机制 2. 基于IP或设备ID的绑定 3. 使用OAuth或第三方认证 4. 利用隐式传递的参数 5. 基于时间戳的签名验证 二、接口测试中网络问题导致无法通过怎么办 1. 重试机制 2. 设置超时时间 3. 使用模拟数据 4. 网络问题的预检测 5. 日志记录与错误分析 6. 切换网络环境 7.

设计表时的三大范式(MySQL)

设计表时的三大范式 什么是范式第一范式第二范式不满足第二范式的缺点数据冗余插入异常更新异常删除异常 第三范式 什么是范式 在表的设计中,范式是一种设计规范,用于更好的组织和管理数据。 设计数据表时的范式有第一范式1NF、第二范式2NF、第三范式3NF等等,一般满足三大范式即可 第一范式 第一范式规定:数据表中的字段不可以再次拆分 只有满足了第一范式,才称得上是关系型数据

win10系统下openssl证书生成和单向认证

文章目录 前言一、安装openssl二、创建证书目录和必要文件1、创建sslcertTest文件夹2、创建openssl.cnf文件3、创建必要文件 三、创建密钥和证书1、创建根证书私钥ca.key2、创建根证书请求文件ca.csr3、创建自签根证书ca.crt4、创建服务端私钥server.key5、创建服务端证书请求文件server.csr6、创建自签服务端证书server.crt 四、

亚信安慧AntDB数据库与华为DPA数据保护一体机完成兼容性互认证,共筑数据安全与效率新高地

近日,湖南亚信安慧科技有限公司(简称“亚信安慧”)与华为技术有限公司(简称“华为”)完成了亚信安慧AntDB数据库与华为DPA数据保护一体机兼容性互认证。 图1:华为DPA数据保护一体机兼容性互认证 亚信安慧AntDB数据库作为领先的数据库解决方案提供商,专注于数据库产品的研发与创新,以其卓越的性能和稳定性,服务于超数亿用户,连续十年无故障运行。亚信安慧AntDB数据库的云原生分布式架