drf三大认证
三大认证流程图
用户群查
router.py
from rest_framework.routers import Route, DynamicRoute, SimpleRouter as DRFSimpleRouter class SimpleRouter(DRFSimpleRouter): routes = [ # List route. /资源s/ Route( url=r'^{prefix}{trailing_slash}$', mapping={ 'get': 'list', # 群查 'post': 'create', # 单增、群增 'put': 'multiple_update', # 群整改 'patch': 'multiple_partial_update', # 群局改 'delete': 'multiple_destroy', # 群删 }, name='{basename}-list', detail=False, initkwargs={'suffix': 'List'} ), # Dynamically generated list routes. Generated using # @action(detail=False) decorator on methods of the viewset. DynamicRoute( url=r'^{prefix}/{url_path}{trailing_slash}$', name='{basename}-{url_name}', detail=False, initkwargs={} ), # Detail route. /资源s/(pk)/ Route( url=r'^{prefix}/{lookup}{trailing_slash}$', mapping={ 'get': 'retrieve', # 单查 'put': 'update', # 单整改 'patch': 'partial_update', # 单局改 'delete': 'destroy' # 单删 }, name='{basename}-detail', detail=True, initkwargs={'suffix': 'Instance'} ), # Dynamically generated detail routes. Generated using # @action(detail=True) decorator on methods of the viewset. DynamicRoute( url=r'^{prefix}/{lookup}/{url_path}{trailing_slash}$', name='{basename}-{url_name}', detail=True, initkwargs={} ), ] # 对外提供router对象 router = SimpleRouter() # eg: router.register('users', UserModelViewSet, basename='user')
url.py
from django.conf.urls import url, include from . import views from .router import router # eg: router.register('users', UserModelViewSet, basename='user') # 两个路由已经匹配了10个方法:get:retrieve、list;post:create、create;put:update、multiple_update # 视图类用ViewSet或GenericViewSet的子类,在子类中实现对应的方法,就可以响应对应的请求 router.register('users', views.UserListViewSet, basename='user') from rest_framework_jwt.views import ObtainJSONWebToken, obtain_jwt_token, refresh_jwt_token, verify_jwt_token urlpatterns = [ url(r'', include(router.urls)) ]
view.py
# 用户群查接口 from rest_framework.viewsets import GenericViewSet from rest_framework import mixins from . import models, serializers, authentications, permissions, throttles from .response import APIResponse class UserListViewSet(mixins.ListModelMixin, GenericViewSet): queryset = models.User.objects.filter(is_active=True).all() serializer_class = serializers.UserModelSerializer # 这些方法名,是在router组件中配置好的,可以从mixins中继承,也可以自定义方法体 def update(self, request, *args, **kwargs): return APIResponse() def multiple_update(self, request, *args, **kwargs): return APIResponse(msg='群改')
认证组件(全局配置)
# settings文件全局配置drf-jwt框架的认证类 REST_FRAMEWORK = { # 认证组件 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_jwt.authentication.JSONWebTokenAuthentication' ], }
authentications.py
from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed # 自定义认证类 # 1) 如果使用session认证,drf默认提供了SessionAuthentication # 2) 如果使用drf-jwt认证框架,drf-jwt框架提供了JSONWebTokenAuthentication # 3) 如果是自定义签发与校验token,才需要将校验token的算法封装到自定义的认证类中 from rest_framework_jwt.authentication import JSONWebTokenAuthentication class MyAuthentication(BaseAuthentication): def authenticate(self, request): """ 1) 从请求头中拿到前台提交的token(一般从HTTP_AUTHORIZATION中拿,也可以与前台约定) -- 如果设置了反爬等措施,校验一下反爬(头 token) 2)没有token,返回None,代表游客 3)有token,进入校验 -- 不通过:抛AuthenticationFailed异常,代表非法用户 -- 通过:返回 (user, token),代表合法用户 """ pass
权限组件
* 视图类局部配置 drf自带 或 自定义 权限类
class MyAPIView(APIView):
permission_classes = [permissions.VIPUserPermission]
* drf自带:IsAuthenticated, IsAdminUser, AllowAny, IsAuthenticatedOrReadOnly
* 自定义:
class VIPUserPermission(BasePermission): # 只要vip分组用户有权限
def has_permission(self, request, view):
for group in request.user.groups.all():
if group.name.lower() == 'vip':
return True # 有权限
return False # 无权限
permissions.py
from rest_framework.permissions import BasePermission """ 自定义权限类 1) drf默认提供了一些权限类 AllowAny:游客和登录用户有全权限 IsAuthenticated:只有登录用户有全权限 IsAdminUser:只有后台用户(admin用户)有全权限 IsAuthenticatedOrReadOnly:游客有读权限,登录用户有全权限 2)如果有特殊需要,需要自定义权限类 如:只有superuser有权限、只有vip用户有权限、只有某ip网段用户有权限、只有某个视图及其子类有权限 """ class MyPermission(BasePermission): def has_permission(self, request, view): """ 1) 根据需求,request和view的辅助,制定权限规则判断条件 2)如果条件通过,返回True 3)如果条件不通过,返回False """ print(request.user, request.auth) return False # VIP用户权限 class VIPUserPermission(BasePermission): def has_permission(self, request, view): for group in request.user.groups.all(): if group.name.lower() == 'vip': return True return False
view.py(局部配置)
# 权限组件 # 配置自定义权限类(有需求) # permission_classes = [permissions.MyPermission] # 配置drf自带的权限类(有需求) from rest_framework.permissions import IsAuthenticated, IsAdminUser, AllowAny, IsAuthenticatedOrReadOnly permission_classes = [IsAuthenticated] permission_classes = [IsAdminUser]