登录认证、认证类、权限类和频率类|登录认证、认证类、权限类和频率类 限制

今日内容概要

  • 认证
  • 频率
  • 权限
内容详细 1、登录认证
# 要求(登录接口): 登陆成功,只要给前端返回json格式字符串 字符串中带一个随机字符串# 登陆认证 判断用户是否登录了 前后端分离---》用不到cookie---》携带随机字符串过来---》通过判断随机字符串判断这个人是否登录了# 登陆接口编写步骤 创建表:User表,一对一UserToken表 前端传入用户名,密码 User表中查,如果能查到---》让他登陆成功 成功后在UserToken中存一条记录---》返回给前端json格式字符串---》字符串中带一个随机字符串

新建项目 创建表 models.py:
from django.db import modelsclass User(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=32) user_type = models.IntegerField(choices=((1, '超级管理员'), (2, '普通管理员'), (3, '普通用户'), (4, '2b用户')))class UserToken(models.Model): user = models.OneToOneField(to=User, on_delete=models.CASCADE) token = models.CharField(max_length=32)# user表中自行添加一条用于测试登录的数据

视图类 views.py功能:
from rest_framework.viewsets import ViewSet from rest_framework.decorators import action from .models import User, UserToken import uuid from rest_framework.response import Response# class UserView(ViewSetMixin,APIView):# 等同下面 class UserView(ViewSet): # authentication_classes = []# 局部禁用@action(methods=['POST'], detail=False) def login(self, request): username = request.data.get('username') password = request.data.get('password') user = User.objects.filter(username=username, password=password).first()if user: # 登陆成功--生成一个随机字符串--存到token表中(如果之前有记录--更新,如果没有--新增) # uuid生成不重复的串---理论上不重复 token = str(uuid.uuid4())# 伪随机数生成,没有参数,重复概率,比其他的高一些 UserToken.objects.update_or_create(user=user, defaults={'token': token})# 如果存在就更新,如果不存在就新增 return Response({'code': 100, 'msg': '登陆成功', 'token': token}) else: return Response({'code': 101, 'msg': '用户名或密码错误'})

修改路由 urls.py:
from django.contrib import admin from django.urls import path, include from rest_framework.routers import SimpleRouter from app01 import viewsrouter = SimpleRouter() router.register('user', views.UserView, 'user') urlpatterns = [ path('admin/', admin.site.urls), path('', include(router.urls)), ]

登录认证、认证类、权限类和频率类|登录认证、认证类、权限类和频率类 限制
文章图片

2、认证类
# 认证类: 用来校验用户是否登录,如果登录了,继续往下走,如果没有登录,直接返回# 编写步骤: 一: 写一个类,继承BaseAuthentication,重写authenticate,在方法中做校验,校验是否登录,返回两个值,没有登录抛异常 二:编写认证类 --》全局使用,局部使用 全局配置:配置文件中: REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.auth.LoginAuth", ] }局部配置:在视图类中 class UserView(ViewSet): authentication_classes = []# 局部禁用局部禁用: class UserView(ViewSet): authentication_classes = []# 局部禁用# 认证类中返回的两个变量,干啥用了 返回的第一个,给了request.user,就是当前登录用户 返回的第二个,给了request.auth,就是token串

在 models.py添加表:
class Book(models.Model): name = models.CharField(max_length=32) price = models.IntegerField() author = models.CharField(max_length=32)# 记得迁移数据库 并添加一条数据用于测试接口

新建 serializer.py:
from rest_framework import serializers from .models import Bookclass BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__'

添加路由 urls.py:
router.register('books', views.BookView, 'books')

新建 auth.py :
from rest_framework.authentication import BaseAuthentication from .models import UserToken from rest_framework.exceptions import AuthenticationFailed# 编写认证类 步骤: # 一: 写一个类,继承BaseAuthentication,重写authenticate,在方法中做校验,校验是否登录,返回两个值,没有登录抛异常 class LoginAuth(BaseAuthentication): def authenticate(self, request): # 前端带过来的token,放在哪,是接口(我们)固定的 token = request.query_params.get('token') user_token = UserToken.objects.filter(token=token).first() if user_token:# 登录了 # 返回两个值:第一个:当前登录用户,第二个:token返回 return user_token.user, token else: # 抛出认证失败的异常 raise AuthenticationFailed('您没有登录')# 二:全局使用,局部使用 # 局部使用:在视图类在中添加:authentication_classes = [LoginAuth, ] # 全局使用:在配置文件中配置

登录认证、认证类、权限类和频率类|登录认证、认证类、权限类和频率类 限制
文章图片

3、权限
# 要求: 用户是普通用户---》普通用户可以访问所有和单条 普通管理员和超级用户可以操作所有,除了访问单条和所有 的那个视图类,还要加上认证类# 跟写认证类步骤差不多 第一步: 写一个类,继承BasePermission,重写has_permission,判断如果有权限,返回True,如果没有权限,返回False 第二步:局部使用和全局使用 局部使用: class BookDetailView(GenericViewSet, CreateModelMixin, DestroyModelMixin, UpdateModelMixin): permission_classes = [UserPermission, ]全局使用:配置文件中配置(一般不建议使用) REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES":["app01.auth.UserPermission",] }

views.py中 添加:
# 权限类功能: from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, UpdateModelMixin# 普通用户,只能查看 class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin): authentication_classes = [LoginAuth, ]# 认证类限制 queryset = Book.objects.all() serializer_class = BookSerializerfrom .auth import UserPermission# 普通用户以上,才能修改 class BookDetailView(GenericViewSet, CreateModelMixin, DestroyModelMixin, UpdateModelMixin): authentication_classes = [LoginAuth, ]# 认证类限制 permission_classes = [UserPermission, ]# 权限限制 queryset = Book.objects.all() serializer_class = BookSerializer

auth.py 中:
# 编写权限类 from rest_framework.permissions import BasePermissionclass UserPermission(BasePermission): def has_permission(self, request, view): self.message = '您是:%s,没有权限' % request.user.get_user_type_display()# 没有权限的提示信息 # 如果有权限,返回True,没有权限返回False # 权限类,在认证类之后,request.user已经有了当前登录用户信息 user_type = request.user.user_type if user_type < 3:# 只要不是1,2,就没有权限 return True else: return False

路由添加 urls.py:
router.register('books', views.BookView, 'books')# 查看一条,和所有router.register('booksdetail', views.BookDetailView, 'booksdetail')# 删除,新增,修改---》权限类加在这里

登录认证、认证类、权限类和频率类|登录认证、认证类、权限类和频率类 限制
文章图片

4、频率限制
# 认证,权限都通过以后,限制某个接口的访问频率 一般根据ip或者用户限制# 使用步骤 第一步: 写一个类,继承SimpleRateThrottle,重写类属性:scope,和get_cache_key方法 get_cache_key返回什么,就以什么做现在,scope配置文件中要用 第二步:在配置文件中配置 # 频率限制 REST_FRAMEWORK = { 'DEFAULT_THROTTLE_RATES': { 'minute_3': '3/m',# 一分钟访问3次 # 'minute_5': '5/m'# 一分钟访问5次 } } 局部使用--视图类中: # 普通用户,只能查看 class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin): authentication_classes = [LoginAuth, ]# 认证类限制 throttle_classes = [IPThrottle]# 频率限制 全局使用--配置文件中: REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': {# 全局配置频率类 'app01.auth.IPThrottle' } }

auth.py中:
# 编写频率限制类 from rest_framework.throttling import SimpleRateThrottleclass IPThrottle(SimpleRateThrottle): scope = 'minute_3'# 随便写def get_cache_key(self, request, view): # 返回什么,就以什么做限制 # 限制ip地址---》就在 request.META字典中---》请求头中数据 return request.META.get('REMOTE_ADDR')# 以客户端ip地址限制 # return request.user.id# 以用户id限制# class UserThrottle(SimpleRateThrottle): #def get_cache_key(self, request, view): #scope = 'minute_5'# 随便写 ## 返回什么,就以什么做限制 ## 限制ip地址---》就在 request.META字典中---》请求头中数据 #return request.user.id# 以用户id限制

views.py 权限类中:
# 普通用户,只能查看 class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin): authentication_classes = [LoginAuth, ]# 认证类限制 throttle_classes = [IPThrottle]# 频率限制

配置文件配置限制:
# 频率限制 REST_FRAMEWORK = { 'DEFAULT_THROTTLE_RATES': { 'minute_3': '3/m',# 一分钟访问3次 # 'minute_5': '5/m'# 一分钟访问5次 } }

【登录认证、认证类、权限类和频率类|登录认证、认证类、权限类和频率类 限制】登录认证、认证类、权限类和频率类|登录认证、认证类、权限类和频率类 限制
文章图片

    推荐阅读