自定义认证类 (登录)
1 使用
from app03 import models
from rest_framework.exceptions import AuthenticationFailed,PermissionDenied,Throttled
#AuthenticationFailed登录认证报错,PermissionDenied权限不通过,Throttled频率太快不允许
from rest_framework.authentication import BaseAuthentication
-定义一个类,继承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 认证类可以配置多个,按照从前向后的顺序执行,如果前面有返回值,认证就不再继续往下走了
url.py:
path('books/',views.BookView.as_view()),
认证功能局部使用和全局使用
1 全局使用(所有接口,都需要登录才能访问) -在配置文件中 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.MyAuthen.LoginAuth", ],
#后续需要加全局认证 直接在这里后面加上即可,k值在
#from rest_framework.views import APIView中的APIView的源码中可以拿到,
例如超级用户权限认证:
"DEFAULT_PERMISSION_CLASSES": ["app名.文件名.类名", ], }
2 局部使用 -在想局部使用的视图类上 authentication_classes = [MyAuthen.LoginAuth,] 3 局部禁用 -在想禁用的视图类上 authentication_classes = []
认证功能源码分析
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, ] 就会执行上面的方法,执行认证
自定义权限功能
from app03 import models from rest_framework.exceptions import AuthenticationFailed,PermissionDenied,Throttled #AuthenticationFailed登录认证报错,PermissionDenied权限不通过,Throttled频率太快不允许 from rest_framework.authentication import BaseAuthentication
1 登录成功以后,超级用户可以干某些事,普通用户不能干---》超级用户可以查看某些接口,普通用户不能查看
2 使用写一个类继承BasePermission,重写has_permission
from rest_framework.permissions import BasePermission class SuperPermission(BasePermission): def has_permission(self,request,view): #超级用户可以访问 除开超级用户都不能访问 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 = []
内置的权限和认证类
# 内置认证类 from rest_framework.exceptions import AuthenticationFailed # 内置权限类 from rest_framework.permissions import BasePermission
1 select_related的使用 articleList=models.Article.objects.select_related("category").all() for article_obj in articleList: # Doesn't hit the database, because article_obj.category # has been prepopulated in the previous query. #不再查询数据库,因为第一次查询,数据已经填充进去了 print(article_obj.category.title)
标签:功能,self,rest,认证,framework,authentication,import,drf From: https://www.cnblogs.com/97zs/p/17956911