【python之DRF学习】三大方法之认证

title:  【python之DRF学习】三大方法之认证
date:  2024-04-17 21:00:56 星期三
updated: 2024-04-17 21:01:00 星期三
description: 
cover: 

内置三大方法:

drf之APIView内部的必须会经过的三大认证/方法:
认证、权限、频率

一、认证组件

1、简介

登录认证的限制

​ 认证组件是drf框架给我们提供的认证接口,它能够在请求进入视图函数/类前进验证(例如:认证用户是否登录),对不符合认证的请求进行拦截并返回校验失败的信息

2、扩展

1、uuid模块:

介绍:用于生成一个随机的字符串
导入模块:import uuid
生成随机字符串:token = str(uuid.uuid4())

3、基于认证类实现用户访问

3.1 使用步骤解析

访问接口,必须登录后才能访问,且保持用户登陆状态

# 有的接口需要登录后才能访问;有的接口,不登录就能访问,这是登录认证的限制   
# 写一个登录接口,返回token。以后只要带着token过来,就是登录了。不带,就没登录。
# 查询所有不需要登录就能访问
# 查询单个,需要登录才能访问

1. 通过认证类完成,使用步骤:
(1)写一个认证类,继承BaseAuthentication;
(2)重写authenicate方法,在内部做认证;
(3)如果认证通过,返回2个值情况;[返回None或两个值]----成功的情况下:(两个值指的是返回用户和token),失败则返回None4)认证不通过抛AuthenticationFailed异常;
(5)只要返回了两个值,在后续的request.user就是当前登录用户;
(6)如果想让某个视图类登录后才能访问    ---局部使用和全局使用

3.2 创建认证文件Authenticate.py

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01.models import UserToken

class LoginAuth(BaseAuthentication):
    def authenticate(self,request):
      #  在这里做认证,校验用户是否登录(带了token,并且能查到,就是登录,返回两个值,否则就是没登录,抛异常)
       # 用户带的token从哪取?后端人员定的:放在请求地址中
        token = request.META.get('HTTP_TOKEN')
       # 通过token表查询该token是否是在表中有记录
        user_token = UserToken.objects.filter(token=token).first()
        if user_token:
            user = user_token.user
            return user,token  # 返回两个值,一个是当前登录用户,一个是token
        else:
            raise AuthenticationFailed('未登陆,无法操作')
            
如果前端带着cookie过来,经过session的中间件,如果登录了,在request.user中就有当前登录用户;
drf没有限制是否登录;
加了这个认证,如果没有登录,就不允许往后访问了.



# 另一种方式:
class LoginAuth(BaseAuthentication):
    def authenticate(self, request):
        # 在这里实现认证,如果是登录的,继续往后走返回两个值,如果不是抛异常
        # 请求中是否携带token,判断是否登录,放在地址栏中
        token = request.query_params.get('token', None)
        if token:  # 前端传入token了,去表中查。如果能查到,登录了,返回两个值[固定的:当前登录用户,token]
            user_token = UserToken.objects.filter(token=token).first()
            if user_token:
                return user_token.user, token
            else:
                # 没有登录抛异常
                raise AuthenticationFailed('token认证失败')
        else:
            raise AuthenticationFailed('token没传')

3.3 视图层的使用方式

# 局部
class BookView(ModelViewSet):
		authentication_classes = [LoginAuth,]

# 方式二:全局配置(settings.py中配置)
	REST_FRAMEWORK={
		'DEFAULT_AUTHENTICATION_CLASSES':['app01.auth.LoginAuth',]}
  
# 局部禁用---》登录接口   (使用全局配置的前提下,当前禁用)
class PublishView(GenericViewSet):
    authentication_classes = []

    
#  登陆成功后如何携带token及返回
@action(methods=['post'], detail=False)
    def login(self, request):
        username = request.data.get('username')
        phone = request.data.get('phone')
        password = request.data.get('password')
        print(username, phone, password)
        user_obj = auth.authenticate(request,username=phone, password=password)
        print(user_obj)
        if user_obj:
       ###### 生成绑定token值并返回到前端####
            # 在userToken表中存储一下:1 从来没有登录过,插入一条,     2 登录过,修改记录
            # 如果有就修改,如果没有就新增  (if 自己写)
            # kwargs 传入的东西查找,能找到,使用defaults的更新,否则新增一条
            token = str(uuid.uuid4())
            UserToken.objects.update_or_create(defaults={'token': token}, user=user_obj)
            return Response({'code': 102, 'msg': '登陆成功', 'token': token})
        else:
            return Response({'code': 103, 'msg': '用户名或者密码错误'})
			#####################################
 

3.4 models

新建userToken表用于反馈用户是否携带token登陆
class UserToken(models.Model):
    token = models.TextField()
    user = models.OneToOneField(to='User', on_delete=models.CASCADE)  # 与前面创建的user表做一对一

当传入错误的token时,返回之前的错误返回信息
image

posted @   Unfool  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示