day86
1 drf认证功能介绍
2 认证功能源码分析
3 自定义认证类(重点)
4 认证功能局部使用和全局使用
5 自定义权限功能(重点)
6 权限功能局部使用和全局使用
7 内置的权限和认证类
## 1 drf认证功能介绍 ```python 0 认证,频率,权限 1 用户是否登录到系统中 2 后期基本上会用JWT的认证 3 自定制的认证 ``` ## 2 认证功能源码分析 ```python 1 APIView---》dispatch---》self.initial(request, *args, **kwargs)--》self.perform_authentication(request)---》Request.user--->self._authenticate(self):Request类的方法---》self.authenticators:Request类的属性---》在Request对象实例化的时候传入的----》Request在什么时候实例化的?dispatch的时候---》APIView:self.get_authenticators()--》return [auth() for auth in self.authentication_classes]----》如果在自己定义的视图类中写了authentication_classes=[类1,类2]----》Request的self.authenticators就变成了我们配置的一个个类的对象 2 self._authenticate(self):Request类的方法 def _authenticate(self): for authenticator in self.authenticators: # BookView中配置的一个个类的对象 try: user_auth_tuple = authenticator.authenticate(self) except exceptions.APIException: self._not_authenticated() raise if user_auth_tuple is not None: self._authenticator = authenticator self.user, self.auth = user_auth_tuple return 3 只要在视图类中配置authentication_classes = [MyAuthen.LoginAuth, ] 就会执行上面的方法,执行认证 ``` ## 3 自定义认证类(重点) ```python 1 使用 -定义一个类,继承BaseAuthentication class LoginAuth(BaseAuthentication): def authenticate(self, request): token = request.GET.get('token') res = models.UserToken.objects.filter(token=token).first() if res: return 元组 else: raise AuthenticationFailed('您没有登录') -重写authenticate方法 -局部使用和全局使用 -局部:在视图类中配置(只要配置了,就是登录以后才能访问,没配置,不用登录就能访问) authentication_classes = [MyAuthen.LoginAuth, ] -全局 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.MyAuthen.LoginAuth", ] } -注意: 1 认证类,认证通过可以返回一个元组,有两个值,第一个值会给,request.user,第二个值会给request.auth 2 认证类可以配置多个,按照从前向后的顺序执行,如果前面有返回值,认证就不再继续往下走了 ``` ## 4 认证功能局部使用和全局使用 ```python 1 全局使用(所有接口,都需要登录才能访问) -在配置文件中 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.MyAuthen.LoginAuth", ] } 2 局部使用 -在想局部使用的视图类上 authentication_classes = [MyAuthen.LoginAuth,] 3 局部禁用 -在想禁用的视图类上 authentication_classes = [] ``` ## 5 自定义权限功能(重点) ```python 1 登录成功以后,超级用户可以干某些事,普通用户不能干---》超级用户可以查看某些接口,普通用户不能查看 2 使用写一个类继承BasePermission,重写has_permission class SuperPermission(BasePermission): def has_permission(self, request, view): # Return `True` if permission is granted, `False` otherwise. # 超级用户可以访问,除了超级用户以外,都不能访问 if request.user.user_type == '1': return True else: return False 3 局部使用和全局使用 -在想局部使用的视图类上 permission_classes = [MyAuthen.SuperPermission] -全局使用 REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES": ["app01.MyAuthen.SuperPermission", ] } -局部禁用 permission_classes = [] ``` ## 6 权限功能局部使用和全局使用 ```python 1 使用方式 -在想局部使用的视图类上 permission_classes = [MyAuthen.SuperPermission] -全局使用 REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES": ["app01.MyAuthen.SuperPermission", ] } -局部禁用 permission_classes = [] ``` ## 7 内置的权限和认证类 ```python # 内置认证类 from rest_framework.exceptions import AuthenticationFailed # 内置权限类 from rest_framework.permissions import BasePermission ```
my_authenticate.py
from rest_framework.authentication import BaseAuthentication from rest_framework.permissions import BasePermission from app01 import models from rest_framework.exceptions import AuthenticationFailed class LoginAuth(BaseAuthentication): def authenticate(self, request): # token放到get请求的参数中或是请求头中 token = request.GET.get('token') res = models.UserToken.objects.filter(token=token).first() if res: return (res.user, token) # 返回一个元组(如果不返回用户对象,后面的权限认证就没有用户对象,只有匿名用户) else: raise AuthenticationFailed('没有登录无法访问') class SuperPermission(BasePermission): message = '您没有访问权限' def has_permission(self, request, view): # user_type = request.user.user_type if request.user.user_type == 1: return True else: return False
views.py
from django.shortcuts import render # Create your views here. from rest_framework.views import APIView from app01 import models from rest_framework.response import Response from app01 import my_authenticate import uuid class BookView(APIView): authentication_classes = [my_authenticate.LoginAuth, ] # 局部使用认证 permission_classes = [my_authenticate.SuperPermission, ] def get(self, request): return Response('获取了所有图书') class PublishView(APIView): authentication_classes = [] # 局部禁用 permission_classes = [] def get(self, request): return Response('获取了所有出版社') class LoginView(APIView): authentication_classes = [] # 局部禁用认证 permission_classes = [] def post(self, request): dic = {'code': 100, 'msg': '登录成功'} username = request.data.get('username') password = request.data.get('password') user = models.User.objects.filter(username=username, password=password).first() if user: token = uuid.uuid4() # 查询该用户是否存在对应的token,若存在,则更新;否则新增 models.UserToken.objects.update_or_create(defaults={'token': token}, user=user) dic['token'] = token return Response(dic) else: dic['code'] = 101 dic['msg'] = '用户名或密码错误' return Response(dic)

浙公网安备 33010602011771号