【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







相关文章
|
2月前
|
数据库 Python
django中数据库外键可以自定义名称吗
django中数据库外键可以自定义名称吗
|
3月前
|
安全 数据库 数据安全/隐私保护
|
3月前
|
SQL Shell API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
|
3月前
|
中间件 API 网络架构
Django后端架构开发:从匿名用户API节流到REST自定义认证
Django后端架构开发:从匿名用户API节流到REST自定义认证
34 0
|
5月前
|
API 数据安全/隐私保护 网络架构
在django3中配置应用的权限
【6月更文挑战第9天】该文档介绍了Django REST Framework的权限管理。总结来说,本文介绍如何设置严格项目权限和如何通过自定义权限控制对特定资源的访问。
52 10
在django3中配置应用的权限
|
5月前
|
安全 API 数据安全/隐私保护
Django REST framework安全实践:轻松实现认证、权限与限流功能
Django REST framework安全实践:轻松实现认证、权限与限流功能
|
5月前
|
安全 API 数据安全/隐私保护
在django3查看项目和编辑应用权限
【6月更文挑战第5天】本文介绍在Django REST Framework中,权限管理对于Web API的安全至关重要。总的来说,应实施严格的项目级别权限,并按需调整视图级别的权限策略,利用DRF的内置权限系统增强安全性。
46 2
|
5月前
|
数据安全/隐私保护 Python
必知的技术知识:django自定义分页器
必知的技术知识:django自定义分页器
|
6月前
|
运维 监控 Serverless
Serverless 应用引擎产品使用之阿里函数计算中在自定义环境下用debian10运行django,用官方层的python3.9,配置好环境变量后发现自定义层的django找不到了如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
3天前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
Python Web框架比较:Django vs Flask vs Pyramid
12 1