认证
设置页面渲染方式
在settings.py文件中加入以下代码
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', # 数据由json渲染 # 当浏览器API渲染打开时,必须打开JSON渲染,而JSON渲染是可以单独打开 'rest_framework.renderers.BrowsableAPIRenderer' # 打开浏览器API渲染 ), }
验证
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认证 ), }
自定义验证,将配置文件中的全局认证注释,然后在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
设置路由
进行数据的迁移后,使用Postman发送请求
打开数据库可看到数据已经添加
自定义认证
- 在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类中的代码
先把原来添加的数据删除后,再次使用Postman携带表单数据发送请求
写上自定义认证的函数
- 在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)
设置路由路径
使用Postman发送请求
获取不到数据的原因是token参数随着时间的变化,与数据库中的token参数不相同,可以通过携带token参数进行访问
权限
权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。
在执行视图的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', ), }
设置局部权限
- 设置局部权限时先把全局权限注释,然后在需要设置权限的视图函数中加上局部权限
导入的模块:
from rest_framework.permissions import IsAuthenticated
自定义权限
自定义权限时需要导入的模块:
from rest_framework.permissions import BasePermission
BasePermission类中有两个方法
写入自定义权限函数
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)
限流
作用:可以对接口访问的频次进行限制,以减轻服务器压力
在配置文件中添加
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次则限流