django rest framework 用户认证
admin
2023-07-18 09:02:28
0次
BaseAuthentication 类:
    django rest framework 通过 BaseAuthentication 实现认证功能
    无论是自定义的认证类还是 rest framework 自带的认证类都应该继承 BaseAuthentication
    BaseAuthentication 中有两个方法 authenticate 和 authenticate_header, 其中 authenticate 方法必须实现
    如果用户需要自定义认证方法则继承 BaseAuthentication 重写 authenticate 方法即可

 
 
models.py

from django.db import models
class UserInfo(models.Model):
        user_type_choices = (
                (1, '普通用户'),
                (2, 'VPI'),
                (3, 'SVPI'),
        )
        user_type = models.IntegerField(choices=user_type_choices)
        username = models.CharField(max_length=32, unique=True)
        password = models.CharField(max_length=64)

class UserToken(models.Model):
        user = models.OneToOneField('UserInfo', models.CASCADE)
        token = models.CharField(max_length=64)

 
 
APP_DIR/utils/auth.py           # 在和 views.py 同级的目录创建 utils 包, 在 utils 中创建 auth.py 文件, 将认证相关的代码放入其中

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

# 实现自定义的认证类
class Authtication(BaseAuthentication):
        def authenticate(self, request):
                # 这儿的 request 对象不是 django 原生的 request 而是 rest_framework 内部进行封装过的 request
                # 使用 request._request 调用 django 原生的 request 对象
                token = request._request.GET.get('token')
                # 检查用户的 token 是否合法
                token_obj = models.UserToken.objects.filter(token=token).first()
                if not token_obj:
                        # rest_framework 会在内部捕捉这个异常并返回给用户认证失败的信息
                        raise exceptions.AuthenticationFailed('用户认证失败')
                # 在 rest_framework 内部会将这两个字段赋值给request以供后续调用
                return (token_obj.user, token_obj)

 
 
views.py

from django.http import JsonResponse
from rest_framework.views import APIView
from app01.utils.auth import Authtication
import hashlib
import time

# 生成 token 字符串
def md5(user):
        ctime = str(time.time())
        m = hashlib.md5(bytes(user, encoding='utf-8'))
        m.update(bytes(ctime, encoding='utf-8'))
        return m.hexdigest()

# 用户登录
class AuthView(APIView):
        def post(self, request):
                ret = {'code':1000, 'msg':None}
                try:
                        user = request._request.POST.get('username')
                        pwd = request._request.POST.get('password')

                        obj = models.UserInfo.objects.filter(username=user, password=pwd).first()
                        if not obj:
                                ret['code'] = 1001
                                ret['msg'] = "用户名或密码错误"
                        # 为登录用户创建token
                        token = md5(user)
                        #存在更新 不存在创建
                        models.UserToken.objects.update_or_create(user=obj, defaults={'token':token})
                        ret['token'] = token
                except:
                        ret['code'] = 1002
                        ret['msg'] = '请求异常'
                return JsonResponse(ret)

# 业务代码
class Order(APIView):
        # 注册自定义的认证类, 可以有多个, 从左到右进行认证匹配
        authentication_classes = [Authtication,]

        def get(self, request):
                # request.user  这个值等于 Authtication 返回的元组的第一个值
                # request.auth  这个值等于 Authtication 返回的元组的第二个值
                ret = {'code':1000, 'msg':None, 'data':None}
                ret['data'] = '欢迎使用本系统'
                return JsonResponse(ret)

 
 
rest_framework 内置的认证类:

BasicAuthentication             # 基于浏览器实现的 Basic 认证, ftp 使用网页登录时使用的就是 Basic 认证
SessionAuthentication           # 基于 django 的 user.is_active 进行认证
TokenAuthentication             # 简单的基于 token 的认证
RemoteUserAuthentication        # 简单的远程用户认证实现

 
 

配置全局生效的认证类和匿名用户:

自定义的认证类如果每次都在指定的类中使用 authentication_classes 指定那么就有可能出现大量的重复代码
我们可以通过全局设置让指定的认证类对继承至 APIView 的所有类生效

settings.py
        REST_FRAMEWORK = {
                # 设置全局生效的认证类(可以有多个)
                # app01 为 django app 的名称
                # utils 为 app 目录下面的 utils 目录(这个目录必须包含 __init__.py 文件)
                # auth 为 utils 目录下面的 auth.py 文件
                # Authtication 为 auth.py 文件里面的 Authtication 类
                # 这儿的设置其实就是使用 from ... import ... 的路径

                'DEFAULT_AUTHENTICATION_CLASSES': ["app01.utils.auth.Authtication",],

                #匿名用户配置
                'UNAUTHENTICATED_USER': None,           # 设置匿名用户的用户名, 默认为 AnonymousUser, 使用 request.user 查看
                'UNAUTHENTICATED_TOKEN': None,          # 设置匿名用户的 token, 默认为 None, 使用 request.auth 查看
        }

 
 

指定 View 类不使用全局的认证类:

在不使用全局认证类的 View 类中添加 authentication_classes = [] 或者 authentication_classes = ['xxxx']
# authentication_classes = [] 表示不使用认证
# authentication_classes = ['xxxx'], xxxx 表示当前类需要使用的认证类用于替换全局类

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...