当前位置: 首页 > news >正文

四、Drf认证组件

四、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、读取请求传递过来的token2、校验合法性3、返回值--3.1返回元组,如(11,22),认证成功,request.user=11,request.auth=22--3.2抛出异常,认证失败,返回错误信息--3.3返回None,多个认证类[类1,类2,类3,类4..。。]-->匿名用户"""def authenticate(self, request):#获取tokentoken=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都为Noneprint('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 AuthenticationFailedclass Myauthentication1(BaseAuthentication):  """用户认证:1、读取请求传递过来的token2、校验合法性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 Noneclass Myauthentication2(BaseAuthentication):"""用户认证:1、读取请求传递过来的token2、校验合法性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则会执行下一个认证类returnclass Noauthentication(BaseAuthentication):"""用户认证:1、读取请求传递过来的token2、校验合法性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',tokenreturn Nonedef authenticate_header(self, request):   #修改认证状态码return "API"

效果:

在这里插入图片描述

4.4子类约束
class Foo(object):def f1(self):#父类的函数中加上一个raiseraise 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 f1raise 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=tokenuser_obj.save()return Response({'status':True,'token':token})

使用postman发送POST请求

在这里插入图片描述

4.5.2查看用户信息
# 视图类
class UserView(APIView):# 需要认证def get(self, request):#返回用户名和tokenreturn 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参数递过来的token2、校验合法性3、返回值认证通过,则返回用户对象和token,不会进入下一个认证类认证失败,返回None,进入下一个认证类"""def authenticate(self, request):#从url参数中获取tokentoken=request.query_params.get('token')if not token:# 如果token不存在,返回None,进行下个认证类return Noneuser_obj=models.User.objects.filter(token=token).first()if user_obj:#如果用户存在,不在进行下个认证类return user_obj,token   #request.user=user_obj,request.auth=token#如果用户不存在,返回None,进行下个认证类return Nonedef authenticate_header(self, request):return "API"class Header_authentication(BaseAuthentication):"""头部认证:1、读取HTTP请求头部传递过来的token2、校验合法性3、返回值认证通过,则返回用户对象和token,不会进入下一个认证类认证失败,返回None,进入下一个认证类"""def authenticate(self, request):#从HTTP请求问部获取tokentoken=request.META.get('HTTP_AUTHENTICATE')if not token:# 如果token不存在,返回None,进行下个认证类return Noneuser_obj=models.User.objects.filter(token=token).first()if user_obj:#如果用户存在,不在进行下个认证类return user_obj,token   #request.user=user_obj,request.auth=token#如果用户不存在,返回None,进行下个认证类return Nonedef 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.lryc.cn/news/453766.html

相关文章:

  • C++:静态成员
  • 28 Vue3之搭建公司级项目规范
  • 【pytorch】张量求导3
  • Servlet——springMvc底层原理
  • Json 在线可视化工具,分享几个
  • LLM | llama.cpp 安装使用(支持CPU、Metal及CUDA的单卡/多卡推理)
  • 矩阵求解复数(aniwoth求解串扰)
  • Redis: Sentinel哨兵监控架构及环境搭建
  • C++ 语言特性30 - 模板介绍
  • 算法笔记(七)——哈希表
  • 【基础算法总结】链表篇
  • 探索路由器静态IP的获取方式
  • Vivado - JTAG to AXI Master (GPIO、IIC、HLS_IP)
  • Java中JWT(JSON Web Token)的运用
  • CSS3练习--电商web
  • Linux 默认内核版本更改
  • 【ubuntu】修改用户名、主机名、主文件夹名、登录名、密码
  • 深入理解JavaScript 的原型继承
  • Error while loading conda entry point: conda-libmamba-solver
  • FANUC机器人—PCDK
  • 如何在wsl中使用beyond compare
  • CNN+Transformer在自然语言处理中的具体应用
  • DotNetty ChannelRead接收数据为null
  • 3分钟学会下载 blender
  • 实现Xshell与虚拟机中Linux服务器的连接(附常见错误解决)
  • Rust 语言开发 ESP32C3 并在 Wokwi 电子模拟器上运行(esp-hal 非标准库、LCD1602、I2C)
  • 项目-坦克大战笔记-墙体销毁以及人机销毁
  • 硬件设计-利用环路设计优化PLL的输出性能
  • Vue入门-Node.js安装
  • OpenCV threhold()函数