四、Drf认证组件

news2024/11/18 13:55:07

四、Drf认证组件

4.1 快速使用

from django.shortcuts import render,HttpResponse
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

# Create your views here.
class Myauthentication(BaseAuthentication):
    """
    用户认证:
    1、读取请求传递过来的token
    2、校验合法性
    3、返回值
        --3.1返回元组,如(11,22),认证成功,request.user=11,request.auth=22
        --3.2抛出异常,认证失败,返回错误信息
        --3.3返回None,多个认证类[类1,类2,类3,类4..。。]-->匿名用户
    """
    def authenticate(self, request):
        #获取token
        token=request.GET.get('token')
        if token:
			#如果token校验成功,则返回一个元组(用户名和token),request.user=元组[0],request.auth=元组[1]
            return 'sally',token
        #如果校验失败则抛出异常
        raise AuthenticationFailed({'code':2000,'error':'认证失败'})

class LoginView(APIView):
    #该视图无需认证
    authentication_classes = []
    def get(self,request):
        #user和auth都为None
        print('user', request.user)
        print('auth', request.auth)
        return Response('login')

class UserView(APIView):
    #该视图要需认证
    authentication_classes = [Myauthentication,]
    def get(self, request):
        #user和auth为认证类Myauthentication返回的结果
        print('user',request.user)
        print('auth',request.auth)
        return Response('user')

class OrderView(APIView):
      #该视图要需认证
    authentication_classes = [Myauthentication, ]
    def get(self, request):
        #user和auth为认证类Myauthentication返回的结果
        print(request.user)
        print(request.auth)
        return Response('order')

认证的全局配置:

上个示例中,需要在每个视图中应用认证类,比较麻烦。

可以在settings.py中做全局配置

REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": None,
    #这里指定一个或多个认证类(注意:认证类不能放在views合局视图文件中,不然会引发循环调用,这里将认证类放在了ext/auth文件中)
    "DEFAULT_AUTHENTICATION_CLASSES":["ext.auth.Myauthentication",]
}

这样,默认所有视图都需要认证,如果某些视图不需要认证,只需要在这些视图函数中加入‘authentication_classes = []’即可。

class LoginView(APIView):
    #不需要认证
    authentication_classes = []
    def get(self,request):
        print('user', request.user)
        print('auth', request.auth)
        return Response('login')

class UserView(APIView):
    # 需要认证
    def get(self, request):
        print('user',request.user)
        print('auth',request.auth)
        return Response('user')

class OrderView(APIView):
    # 需要认证
    def get(self, request):
        print(request.user)
        print(request.auth)
        return Response('order')

4.2多个认证类

settings.py
REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": None,
    "DEFAULT_AUTHENTICATION_CLASSES":["ext.auth.Myauthentication1",
                                      "ext.auth.Myauthentication2",
                                      "ext.auth.Noauthentication",]
}

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

class Myauthentication1(BaseAuthentication):  
    """
    用户认证:
    1、读取请求传递过来的token
    2、校验合法性
    3、返回值
        --3.1返回元组,如(11,22),认证成功,request.user=11,request.auth=22
        --3.2抛出异常,认证失败,返回错误信息
        --3.3返回None,多个认证类[类1,类2,类3,类4..。。]-->匿名用户
    """
    def authenticate(self, request):
        token=request.GET.get('token')

        if token=='123':
        	#如果验证成功,则返回用户名和token,不再执行下一个认证类
            print(token)
            return 'sally',token
        #如果验证失败,则返回None,如果返回None则会执行下一个认证类
        return None

class Myauthentication2(BaseAuthentication):
    """
    用户认证:
    1、读取请求传递过来的token
    2、校验合法性
    3、返回值
        --3.1返回元组,如(11,22),认证成功,request.user=11,request.auth=22
        --3.2抛出异常,认证失败,返回错误信息
        --3.3返回None,多个认证类[类1,类2,类3,类4..。。]-->匿名用户
    """

    def authenticate(self, request):
        token = request.GET.get('token')

        if token == '456':
        	#如果验证成功,则返回用户名和token,不再执行下一个认证类
            print(token)
            return 'ying',token
         #如果验证失败,则返回None,如果返回None则会执行下一个认证类
        return

class Noauthentication(BaseAuthentication):
    """
    用户认证:
    1、读取请求传递过来的token
    2、校验合法性
    3、返回值
        --3.1返回元组,如(11,22),认证成功,request.user=11,request.auth=22
        --3.2抛出异常,认证失败,返回错误信息
        --3.3返回None,多个认证类[类1,类2,类3,类4..。。]-->匿名用户
    """

    def authenticate(self, request):
        print('认证失败')
        #如果以上的认证类认证全部失败,则抛出错误,认证失败。
        raise AuthenticationFailed({'code':2000,'error':'认证失败'})

4.3认证状态码

class Myauthentication1(BaseAuthentication):
 
    def authenticate(self, request):
        token=request.GET.get('token')

        if token=='123':
            print(token)
            return 'sally',token
        return None
    def authenticate_header(self, request):   
        #修改认证状态码
        return "API"

效果:

在这里插入图片描述

4.4子类约束
class Foo(object):
    def f1(self):
        
    	#父类的函数中加上一个raise
        raise NotImplementedError
class New(Foo):
    def f2(self):
        #如果子类定义了一个父类中不存在的方法,则会报错
        print('f1')


obj=New()
Traceback (most recent call last):
  File "G:\py_project\api\app_api\tests.py", line 70, in <module>
    obj.f1()
  File "G:\py_project\api\app_api\tests.py", line 61, in f1
    raise NotImplementedError
NotImplementedError

4.5示例:用户登入和查看用户信息

4.5.1创建用户表
class User(models.Model):
    name=models.CharField(verbose_name='name',max_length=64)
    password=models.CharField(verbose_name='password',max_length=64)
    token=models.CharField(verbose_name='token',max_length=64,null=True,blank=True)
4.5.2用户登入
class LoginView(APIView):
    #不需要认证
    authentication_classes = []
    def post(self,request):
        #获取用户通过POST方式传递过来的用户名和密码
        name=request.data.get('name')
        password=request.data.get('password')
        print(name,password)
        #尝试获取用户对象
        user_obj=models.User.objects.filter(name=name,password=password).first()
        if not user_obj:
            #如果用户对象不存在,代表用户名密码错误
            return Response({'status':False,'errMsg':'用户名或密码错误'})
        #为用户生成一个token并保存到数据库
        token=str(uuid.uuid4())
        user_obj.token=token
        user_obj.save()


        return Response({'status':True,'token':token})

使用postman发送POST请求

在这里插入图片描述

4.5.2查看用户信息
# 视图类
class UserView(APIView):
    # 需要认证
    def get(self, request):
        #返回用户名和token
        return Response({'user':request.user.name,'token':request.auth})
#settings.py
REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": None,
    #先认证URL参数中的token,如果认证失败则认证HTTP请求头部中的token,如果认证失败则进入未认证程序
    "DEFAULT_AUTHENTICATION_CLASSES":["ext.auth.Query_Params_authentication",
                                      "ext.auth.Header_authentication",
                                      "ext.auth.Noauthentication",]
}
#ext.auth
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app_api import models
class Query_Params_authentication(BaseAuthentication):
    """
    url参数认证:
    1、读取请求url参数递过来的token
    2、校验合法性
    3、返回值
        认证通过,则返回用户对象和token,不会进入下一个认证类
        认证失败,返回None,进入下一个认证类
    """
    def authenticate(self, request):
        #从url参数中获取token
        token=request.query_params.get('token')
        if not token:
            # 如果token不存在,返回None,进行下个认证类
            return None
        user_obj=models.User.objects.filter(token=token).first()
        if user_obj:
            #如果用户存在,不在进行下个认证类
            return user_obj,token   #request.user=user_obj,request.auth=token
        #如果用户不存在,返回None,进行下个认证类
        return None

    def authenticate_header(self, request):
        return "API"

class Header_authentication(BaseAuthentication):
    """
    头部认证:
    1、读取HTTP请求头部传递过来的token
    2、校验合法性
    3、返回值
        认证通过,则返回用户对象和token,不会进入下一个认证类
        认证失败,返回None,进入下一个认证类
    """
    def authenticate(self, request):
        #从HTTP请求问部获取token
        token=request.META.get('HTTP_AUTHENTICATE')
        if not token:
            # 如果token不存在,返回None,进行下个认证类
            return None
        user_obj=models.User.objects.filter(token=token).first()
        if user_obj:
            #如果用户存在,不在进行下个认证类
            return user_obj,token   #request.user=user_obj,request.auth=token
        #如果用户不存在,返回None,进行下个认证类
        return None

    def authenticate_header(self, request):
        return "API"

class Noauthentication(BaseAuthentication):
    """
    未通过上面两次认证的,直接抛出错误:

    """

    def authenticate(self, request):
        #如果以上的认证类认证全部失败,则抛出错误,认证失败。
        raise AuthenticationFailed({'code':2000,'error':'认证失败'})

使用postman进行测试

1)url参数中传递token

在这里插入图片描述

2)HTTP头部传递token

在这里插入图片描述

3)token错误

在这里插入图片描述

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

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

相关文章

win11 升级报 0x80073713 错误

安装错误 - 0x80073713 通常是由于系统文件损坏或 Windows Update 组件异常引起的。‌ 这个问题可能阻止您的系统正常接收和安装更新&#xff0c;影响系统的稳定性和安全性。 可以尝试如下如下方法&#xff1a; 首先&#xff0c;您可以尝试使用命令提示符运行系统文件检查器…

资源《Arduino 扩展板2-矩阵按钮 》说明。

资源链接&#xff1a; Arduino 扩展板2-矩阵按钮 1.文件明细 2.文件内容说明 包含&#xff1a;AD工程、原理图、PCB。 3.内容展示 4.简述 该文件为PCB工程&#xff0c;采用AD做的。 该文件打板后配合Arduino使用&#xff0c;属于Arduino的扩展板。 该文件主要有16个按钮…

wgan的实现的伪代码,和原理,dcgan,模型坍塌 em距离 js kl散

原文地址 https://blog.csdn.net/Keep_Trying_Go/article/details/130471766 伪代码详细看这个&#xff0c; 特别注意点&#xff1a;gan(xnosize) 生成器 是 输入噪声 &#xff0c;而不是全部噪声生成的 特别注意点&#xff1a;gan(xnosize) 生成器 是 输入噪声 &#…

vue3使用Teleport 控制台报警告:Invalid Teleport target on mount: null (object)

Failed to locate Teleport target with selector “.demon”. Note the target element must exist before the component is mounted - i.e. the target cannot be rendered by the component itself, and ideally should be outside of the entire Vue component tree main.…

基于SSM+小程序的选课管理系统2(源码+sql脚本+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 ​ 教师的账号和密码可以注册&#xff0c;管理员的账号和密码可由系统开发者在数据库中设置&#xff0c;学生的账号和密码可以由注册获得。 1、管理员的主要功能为学生资料、教师资料的添…

如何升级OCAT

如何升级OCAT 一. 从官网下载OCAT 官网下载地址链接&#xff1a;https://github.com/ic005k/OCAuxiliaryTools/releases 目前下载下来版本为0.8.8&#xff0c;但RapidEFI显示最新版本已经为1.0.1。 为了防止OC版本过低导致进不了系统&#xff0c;需要对OCAT进行升级。![在这里…

.NET 一款支持冰蝎的免杀WebShell

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

探索 PixiJS:强大的 2D 图形渲染库

探索 PixiJS&#xff1a;强大的 2D 图形渲染库 演示地址 演示地址 源码地址 源码地址 获取更多 获取更多 随着 Web 技术的发展&#xff0c;越来越多的开发者希望在网页中实现丰富的视觉效果和动画。PixiJS 作为一个高性能的 2D 渲染库&#xff0c;凭借其强大的功能和易用性…

《NoSQL》非关系型数据库MongoDB 学习笔记!

Mongo基础&#xff1a; 使用数据库&#xff1a; 使用use 命令 后面跟着要使用的数据库名字即可&#xff0c; 例如&#xff1a;use cities, 值得注意的是&#xff0c; mongo中不像mysql&#xff0c; 还需要先创建数据库&#xff0c;后访问&#xff0c; mongo中&#xff0c;你无…

媒介坊:在数字化时代,企业如何在竞争激烈的市场中脱颖而出

在当今的数字化时代&#xff0c;企业如何在竞争激烈的市场中脱颖而出&#xff0c;成为消费者关注的焦点&#xff1f;软文投放作为一种高效的营销手段&#xff0c;正受到越来越多企业的青睐。而媒介坊&#xff0c;作为一站式软文投放平台&#xff0c;正是帮助企业实现这一目标的…

Android Camera2 与 Camera API技术探究和RAW数据采集

Android Camera2 Android Camera2 是 Android 系统中用于相机操作的一套高级应用程序接口&#xff08;API&#xff09;&#xff0c;它取代了之前的 Camera API。以下是关于 Android Camera2 的一些主要信息&#xff1a; 主要特点&#xff1a; 强大的控制能力&#xff1a;提供…

JavaWeb——Vue组件库Element(4/6):案例:基本页面布局(基本框架、页面布局、CSS样式、完善布局、效果展示,含完整代码)

目录 步骤 基本页面布局 基本框架 页面布局 CSS样式 完善布局 效果展示 完整代码 Element 的基本使用方式以及常见的组件已经了解完了&#xff0c;接下来要完成一个案例&#xff0c;通过这个案例让大家知道如何基于 Element 中的各个组件制作一个完整的页面。 案例&am…

Labview helper

IMAQ Advanced Setup Learn Geometric Pattern 2 VI 参数说明Curve Extraction Mode (0)指定VI如何识别图像中的曲线。如果您希望VI不对图像中对象的均匀性或图像背景做出任何假设&#xff0c;请将此选项设置为正常。如果您希望VI假定图像中的对象或图像背景由均匀的像素值组成…

PCL 最远点采样(FPS)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 可视化函数 2.1.2 最远点采样 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#xff0…

事务原理,以及MVCC如何实现RC,RR隔离级别的

事务原理 redo log 保持持久性&#xff1a; 首先原来的情况是我们做一组操作的时候&#xff0c;先去操作bufferpool缓冲区&#xff0c;如果没有&#xff0c;那么后台线程将数据页换入换出到缓冲区&#xff0c;然后我们对这个buffer pool进行修改&#xff0c;为脏页&#xff0c…

Redis篇(Redis原理 - 数据结构)(持续更新迭代)

目录 一、动态字符串 二、intset 三、Dict 1. 简介 2. Dict的扩容 3. Dict的rehash 4. 知识小结 四、ZipList 1. 简介 2. ZipListEntry 3. Encoding编码 五、ZipList的连锁更新问题 六、QuickList 七、SkipList 八、RedisObject 1. 什么是 redisObject 2. Redi…

开放式耳机哪个品牌好?2024年蓝牙耳机排行榜

开放式蓝牙耳机以其独树一帜的佩戴方式&#xff0c;正逐渐成为音乐爱好者和运动达人的新宠。时尚而又实用。如果你对传统耳机的佩戴方式感到厌倦&#xff0c;或者在寻找一款既能提供高品质音乐体验又能兼顾佩戴舒适性的耳机&#xff0c;那么开放式蓝牙耳机可能会是你的理想选择…

Vue3轻松实现前端打印功能

文章目录 1.前言2.安装配置2.1 下载安装2.2 main.js 全局配置3.综合案例3.1 设置打印区域3.2 绑定打印事件3.3 完整代码4.避坑4.1 打印表格无边框4.2 单选框复选框打印不选中4.3 去除页脚页眉4.4 打印內容不自动换行1.前言 vue3 前端打印功能主要通过插件来实现。 市面上常用的…

【CKA】八、扩容Deployment

8、扩容Deployment 1. 考题内容&#xff1a; 2. 答题思路&#xff1a; 直接使用命令扩容就行 我考的题只是把 loadbalancer 名字换了 &#xff0c;其他都一模一样 3. 官网地址&#xff1a; https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/ …

Golang | Leetcode Golang题解之第451题根据字符出现频率排序

题目&#xff1a; 题解&#xff1a; func frequencySort(s string) string {cnt : map[byte]int{}maxFreq : 0for i : range s {cnt[s[i]]maxFreq max(maxFreq, cnt[s[i]])}buckets : make([][]byte, maxFreq1)for ch, c : range cnt {buckets[c] append(buckets[c], ch)}an…