1. 程式人生 > >Django rest framework 權限操作(源碼分析二)

Django rest framework 權限操作(源碼分析二)

prop 源碼 display rtc body app ffi 代碼 tin

知識回顧

這一篇是基於上一篇寫的,上一篇謝了認證的具體流程,看懂了上一篇這一篇才能看懂,

當用戶訪問是 首先執行dispatch函數,當執行當第二部時:

   #2.處理版本信息 處理認證信息 處理權限信息 對用戶的訪問頻率進行限制
            self.initial(request, *args, **kwargs)

進入到initial方法:

技術分享圖片
 def initial(self, request, *args, **kwargs):
        """
        Runs anything that needs to occur prior to calling the method handler.
        
""" self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use.
#2.1處理版本信息 version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted #2.2處理認證信息 self.perform_authentication(request)
#2.3處理權限信息 self.check_permissions(request) #2.4對用戶的訪問頻率進行限制 self.check_throttles(request)
技術分享圖片
 #2.3處理權限信息
        self.check_permissions(request)

下面 開始 權限的具體分析:

進入到check_permissions函數中

技術分享圖片
 #檢查權限
    def check_permissions(self, request):
        """
        Check if the request should be permitted.
        Raises an appropriate exception if the request is not permitted.
        """
        #elf.get_permissions()得到的是一個權限對象列表
        for permission in self.get_permissions():
            #在自定義的Permission中has_permission方法是必須要有的
            #判斷當前has_permission返回的是True,False,還是拋出異常
            #如果是True則表示權限通過,False執行下面代碼
            if not permission.has_permission(request, self):
                #為False的話則拋出異常,當然這個異常返回的提示信息是英文的,如果我們想讓他顯示我們自定義的提示信息
                #我們重寫permission_denied方法即可
                self.permission_denied(
                    #從自定義的Permission類中獲取message(權限錯誤提示信息),一般自定義的話都建議寫上,如果沒有則為默認的(英文提示)
                    request, message=getattr(permission, message, None)
                )
技術分享圖片

查看permission_denied方法(如果has_permission返回True則不執行該方法)

技術分享圖片
 def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """
        if request.authenticators and not request.successful_authenticator:
            #沒有登錄提示的錯誤信息
            raise exceptions.NotAuthenticated()
        #一般是登陸了但是沒有權限提示
        raise exceptions.PermissionDenied(detail=message)
技術分享圖片

舉例:

技術分享圖片
from django.db import models

# Create your models here.
class Userinfo(models.Model):
    name=models.CharField(max_length=32,verbose_name=用戶名)
    pwd=models.CharField(max_length=32,verbose_name=密碼)
    token=models.CharField(max_length=64,null=True)

    def __str__(self):
        return self.name
models 技術分享圖片
urlpatterns = [
    url(r^p/, app02_views.Pview.as_view()),
    url(r^mp/, app02_views.Aview.as_view()),
    url(r^jp/, app02_views.Jview.as_view()),
]
urls 技術分享圖片
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework import exceptions


from app01 import models
# Create your views here.

class MyAuthentication(BaseAuthentication):

    def authenticate(self, request):
        token=request.query_params.get(token)
        user=models.Userinfo.objects.filter(token=token).first()
        if user:
            return (user.name,user)
        return None

class MyPermission(object):
    message = 登錄才可以訪問
    def has_permission(self,request, view):
        if request.user:
            return True
        return False

class AdminPermission(object):
    message = 會員才可以訪問
    def has_permission(self,request,view):
        if request.user==ctz:
            return True
        return False

class Pview(APIView):
    ‘‘‘
    所有人都可以看
    ‘‘‘
    authentication_classes = [MyAuthentication,]
    permission_classes = []
    def get(self,request):
        return Response(圖片列表)
    def post(self,request):
        pass




class Aview(APIView):
    ‘‘‘
    登錄的人可以看
    ‘‘‘
    authentication_classes = [MyAuthentication,]
    permission_classes = [MyPermission,]
    def get(self,request):
        return Response(美國電影列表)
    def post(self,request):
        pass

    def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """

        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated(無權訪問)
        raise exceptions.PermissionDenied(detail=message)

class Jview(APIView):
    ‘‘‘
    會員才可以看
    ‘‘‘
    authentication_classes = [MyAuthentication,]
    permission_classes = [MyPermission,AdminPermission,]
    def get(self,request):
        return Response(日本電影列表)
    def post(self,request):
        pass

    def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """

        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated(無權訪問)
        raise exceptions.PermissionDenied(detail=message)
Views

上面的是局部的只能在當前類中可以用,如果想在全局中用:只需要在settings中配置即可:

技術分享圖片
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework import exceptions

from app02.utils import MyPermission
#
#
from app01 import models
# # Create your views here.
#
# class MyAuthentication(BaseAuthentication):
#
#     def authenticate(self, request):
#         token=request.query_params.get(‘token‘)
#         user=models.Userinfo.objects.filter(token=token).first()
#         if user:
#             return (user.name,user)
#         return None
#
# class MyPermission(object):
#     message = ‘登錄才可以訪問‘
#     def has_permission(self,request, view):
#         if request.user:
#             return True
#         return False
#
# class AdminPermission(object):
#     message = ‘會員才可以訪問‘
#     def has_permission(self,request,view):
#         if request.user==‘ctz‘:
#             return True
#         return False

class Pview(APIView):
    ‘‘‘
    所有人都可以看
    ‘‘‘

    permission_classes = []
    def get(self,request):
        return Response(圖片列表)
    def post(self,request):
        pass




class Aview(APIView):
    ‘‘‘
    登錄的人可以看
    ‘‘‘
  #  authentication_classes = [MyAuthentication,]
    permission_classes = [MyPermission,]
    def get(self,request):
        return Response(美國電影列表)
    def post(self,request):
        pass

    def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """

        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated(無權訪問)
        raise exceptions.PermissionDenied(detail=message)

class Jview(APIView):
    ‘‘‘
    會員才可以看
    ‘‘‘
    # authentication_classes = [MyAuthentication,]
    # permission_classes = [MyPermission,AdminPermission,]
    def get(self,request):
        return Response(日本電影列表)
    def post(self,request):
        pass

    def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """

        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated(無權訪問)
        raise exceptions.PermissionDenied(detail=message)
Views 技術分享圖片
from django.shortcuts import render

from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework import exceptions
from rest_framework.exceptions import APIException


from app01 import models
# Create your views here.

class MyAuthentication(BaseAuthentication):

    def authenticate(self, request):
        token=request.query_params.get(token)
        user=models.Userinfo.objects.filter(token=token).first()
        if user:
            return (user.name,user)
        return None

class MyPermission(object):
    message = 登錄才可以訪問
    def has_permission(self,request, view):
        if request.user:
            return True
        return False

class AdminPermission(object):
    message = 會員才可以訪問
    def has_permission(self,request,view):
        if request.user==ctz:
            return True
        return False
utils 技術分享圖片
REST_FRAMEWORK = {
    UNAUTHENTICATED_USER: None,
    UNAUTHENTICATED_TOKEN: None,
    "DEFAULT_AUTHENTICATION_CLASSES": [
      # "app01.utils.MyAuthentication",
        "app02.utils.MyAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES":[
       "app02.utils.MyPermission",
       "app02.utils.AdminPermission",
    ],
}
settings

Django rest framework 權限操作(源碼分析二)