【Django学习笔记 - 19】:认证、自定义认证、权限、限流

简介: 【Django学习笔记 - 19】:认证、自定义认证、权限、限流

认证


设置页面渲染方式


   在settings.py文件中加入以下代码

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',    # 数据由json渲染
        # 当浏览器API渲染打开时,必须打开JSON渲染,而JSON渲染是可以单独打开
        'rest_framework.renderers.BrowsableAPIRenderer'     # 打开浏览器API渲染
    ),
}


56455003b2c748b386d3c8089324fe89.png


验证


1、将Django中自带的用户认证模型继承出来


创建一个子应用:user,并在models.py文件中写入继承用户认证的函数

from django.db import models
from django.contrib.auth.models import AbstractUser
# AbstractUser 是 Django中自带的用户认证模型
class UserInfo(AbstractUser):
    type_ = (
        ('1', '普通用户'),
        ('2', 'vip用户'),
        ('3', 'svip用户')
    )
    mobile = models.CharField(verbose_name='手机号', max_length=11)
    user_type = models.CharField(choices=type_, max_length=8, verbose_name='用户类型')
    class Meta:
        db_table = 'user'


2、在配置文件(settings.py)中指定用于验证的用户模型的位置(‘应用名.模型类名’)


注意:如果一个项目中用到的用户验证模型,那么在第一次迁移之前就要定义好这个用户验证模型

AUTH_USER_MODEL = 'user.UserInfo'



3、实现验证方法


  • 全局认证,在配置文件中写入以下代码
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',    # 数据由json渲染
        # 当浏览器API渲染打开时,必须打开JSON渲染,而JSON渲染是可以单独打开
        'rest_framework.renderers.BrowsableAPIRenderer'     # 打开浏览器API渲染
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',   # 基本认证
        'rest_framework.authentication.SessionAuthentication',   # session认证
    ),
}



4c6a373c2b59419d9fd4e813c069a621.png

自定义验证,将配置文件中的全局认证注释,然后在views.py文件中写入自定义验证的代码

from rest_framework.response import Response
from rest_framework.views import APIView
class Registerview(APIView):
    def post(self, request):
        data = request.data
        username = data.get('username')
        password = data.get('password')
        user = UserInfo.objects.create(username=username, password=password)
        token = create_token(username)
        return Response(token)
# 自定义加密方法
def create_token(username):
    """
    加密,生成用户的token
    :param username:
    :return:
    """
    import hashlib
    import time
    m = hashlib.md5()   # 实例化md5对象
    data = username + str(time.time())  # 将用户名和当前的时间戳拼接
    m.update(data.encode())     # 编码并传入data
    result = m.hexdigest()  # 加密后的数据
    return result


设置路由

077616e048ee4a62a20ef6cf57c40557.png

进行数据的迁移后,使用Postman发送请求


3c38f4666c6a409db629fa655e46eede.png

打开数据库可看到数据已经添加

4ce114cb21f941d18d074bd814c49c0b.png




自定义认证


  • 在models.py文件中写上带用token字段的模型
class TokenModel(models.Model):
    user = models.OneToOneField(UserInfo, on_delete=models.CASCADE, verbose_name='用户')
    token = models.CharField(max_length=64, verbose_name='钥匙')
    class Meta:
        db_table = 'user_token'


进行数据迁移后,修改Registerview类中的代码

d5a6b5f1a2c84c1cb8e3ce7617965fda.png

先把原来添加的数据删除后,再次使用Postman携带表单数据发送请求

e5eb607bab5b454bbe66456d4bd45b59.png

5777064730704bbdb5502e8b234dcdb7.png

2964368bbf974ec692686635928b2224.png


写上自定义认证的函数


  • 在user应用的view.py文件中写上自定义认证的函数,该函数继承BaseAuthentication
from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        try:
            req_token = request.data.get('token')
            token_obj = TokenModel.objects.get(token = req_token)
            if req_token == token_obj.token:
                return (token_obj.user, token_obj)  
            else:
                raise exceptions.AuthenticationFailed('请登录(服务器没有找到当前用户的token参数)')
        except:
            raise exceptions.AuthenticationFailed('请登录(服务器没有找到当前用户的token参数)')
        # 返回值为元组类型,元组中是两个元素(对象),第一个为token对应的用户对象,第二个为token对象



写上登录后返回数据的函数

class LoginView(APIView):
    authentication_classes = [MyAuthentication] # 重写认证方法,使用自定义的认证方法
    def post(self, request):
      husband = Husband_1.objects.all()
      serializer = HusbandSerializer(husband, many=True)
      return Response(serializer.data)


设置路由路径


23f4443548c742d8b4e1ac94dc6c2770.png

使用Postman发送请求

c3be4a97adaf46a792d61032849b4ced.png

获取不到数据的原因是token参数随着时间的变化,与数据库中的token参数不相同,可以通过携带token参数进行访问

fad3c1f93ab445d2be067d2c7ce5855f.png

权限


权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。


   在执行视图的dispatch()方法前,会先进行视图访问权限的判断

   在通过get_object()获取具体对象时,会进行对象访问权限的判断


使用方法:


   在配置文件中设置默认的权限管理类

   在具体的视图中通过permission_classes属性来设置


提供的权限:


   AllowAny 允许所有用户?

   lsAuthenticated仅通过认证的用户

   lsAdminUser仅管理员用户

   lsAuthenticatedOrReadOnly认证的用户可以完全操作,否则只能get读取



设置全局权限

   设置全局权限可在配置文件中添加以下代码


REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',    # 数据由json渲染
        # 当浏览器API渲染打开时,必须打开JSON渲染,而JSON渲染是可以单独打开
        # 'rest_framework.renderers.BrowsableAPIRenderer'     # 打开浏览器API渲染
    ),
    # 'DEFAULT_AUTHENTICATION_CLASSES': (
        # 'rest_framework.authentication.BasicAuthentication',   # 基本认证
        # 'rest_framework.authentication.SessionAuthentication',   # session认证
    # ),
    # 设置全局权限
     'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}



b01c3d28127945f4acada48dc0a124b2.png

设置局部权限

  • 设置局部权限时先把全局权限注释,然后在需要设置权限的视图函数中加上局部权限


导入的模块:

from rest_framework.permissions import IsAuthenticated


873ffb8071a64dfba07b2fb585c430b8.png

80b5c5e88c924bf4a405c1dddb5c620a.png




自定义权限


自定义权限时需要导入的模块:

from rest_framework.permissions import BasePermission


BasePermission类中有两个方法


d00e652e50bd4412b42d5029dd1a0b66.png


写入自定义权限函数

class MyPermission(BasePermission):
    """根据用户的等级来设置用户权限"""
    def has_permission(self, request, view):
        user_type = request.user.user_type
        if not user_type:
            return False
        else:
            return True


  • 在LoginView中使用自定的权限

设置一个普通用户只能看到一条数据,vip用户能看到5条数据,svip用户没有限制

class LoginView(APIView):
    authentication_classes = [MyAuthentication]
    permission_classes = [MyPermission] # 使用自定义的权限
    def post(self, request):
        husband = Husband_1.objects.all()
        if request.user.user_type == '1':
            serializer = HusbandSerializer(husband[0])
            return Response(serializer.data)
        elif request.user.user_type == '2':
            serializer = HusbandSerializer(husband[:5], many=True)
            return Response(serializer.data)
        serializer = HusbandSerializer(husband, many=True)
        return Response(serializer.data)

73edf899190a4afb985ee624e818f802.png


8b3b32d657d1497cac1cfad310c9ceef.png




限流



作用:可以对接口访问的频次进行限制,以减轻服务器压力

在配置文件中添加

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',    # 数据由json渲染
        # 当浏览器API渲染打开时,必须打开JSON渲染,而JSON渲染是可以单独打开
        # 'rest_framework.renderers.BrowsableAPIRenderer'     # 打开浏览器API渲染
    ),
    # 'DEFAULT_AUTHENTICATION_CLASSES': (
        # 'rest_framework.authentication.BasicAuthentication',   # 基本认证
        # 'rest_framework.authentication.SessionAuthentication',   # session认证
    # ),
    # 设置限流
    # 'DEFAULT_PERMISSION_CLASSES': (
        # 'rest_framework.permissions.IsAuthenticated',
    # ),
    'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle', # 用于限制未认证用户的请求频率,主要根据用户的 IP地址来确定用户身份。(匿名用户,也就没有登录的用户,根据发起请求的IP)
            'rest_framework.throttling.UserRateThrottle'  # 已登录的用户限流(根据已登录用户的id进行限流)
            ), # 用于限定认证用户的请求频率,可对不同类型的用户实施不同的限流政策。
    'DEFAULT_THROTTLE_RATES': {
            'anon': '100/day',   # ip   键名不要更换为别的   此处就是对匿名用户进行周期性限流
            'user': '1000/day'   # 用户id
        }
}


例:设置为一分钟访问5次则限流

944881be07334d48adce52f344dcb9e5.png


53f182ec6a7c4afdba2bdee4a8fd56a2.png15607274f0ba4f17ab6e358b21ebdaf1.png







相关文章
|
8月前
|
缓存 监控 中间件
Django中间件自定义开发指南:从原理到实战的深度解析
Django中间件是Web应用的“交通警察”,在请求与响应过程中进行全局处理,适用于身份验证、日志记录、性能监控等功能。本文详解中间件的工作原理、开发步骤及实战案例,帮助开发者掌握自定义中间件的构建方法,提升Django应用的可维护性与扩展性。
470 0
|
9月前
|
Shell 数据库 网络架构
Django+DRF 实战:从异常捕获到自定义错误信息(下)
本文详解了 Django REST Framework 中 ValidationError 的验证流程与优先级,涵盖字段内置验证、自定义验证方法、对象级验证及数据库约束,并通过实战演示如何自定义异常提示信息。
218 1
Django+DRF 实战:从异常捕获到自定义错误信息(下)
|
9月前
|
Python
Django+DRF 实战:自定义异常处理流程
本文详解DRF异常处理流程,包括默认处理机制与自定义异常处理器的实现方法。通过源码分析和实战示例,讲解如何全局捕获并统一返回错误信息,并结合日志记录与友好提示提升项目健壮性。适用于Django进阶开发。
316 4
|
10月前
|
中间件 数据库 Python
Django实战:自定义中间件实现全链路操作日志记录
Django中间件是一套轻量级插件系统,用于全局处理请求与响应。通过自定义中间件可实现如操作日志记录等功能,支持在请求、视图、响应及异常阶段插入逻辑。本文详解中间件生命周期、编写方式及实战案例。
249 1
|
9月前
|
数据安全/隐私保护 网络架构 UED
Django+DRF 实战:从异常捕获到自定义错误信息
本文介绍了DRF(Django REST framework)中的异常处理机制,重点讲解了内置异常类ValidationError的使用场景与示例。同时通过用户注册功能的实战演示,展示了如何在序列化器中自定义参数校验规则,并在视图中捕获并返回结构化的错误信息,提升接口的健壮性与用户体验。
199 0
|
安全 数据库 数据安全/隐私保护
|
数据库 Python
django中数据库外键可以自定义名称吗
django中数据库外键可以自定义名称吗
|
SQL Shell API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
|
中间件 API 网络架构
Django后端架构开发:从匿名用户API节流到REST自定义认证
Django后端架构开发:从匿名用户API节流到REST自定义认证
408 0