溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Django-Rest-Framework權限管理源碼的示例分析

發(fā)布時間:2021-09-09 10:05:00 來源:億速云 閱讀:152 作者:小新 欄目:開發(fā)技術

這篇文章主要介紹了Django-Rest-Framework權限管理源碼的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

在django的views中不論是用類方式還是用裝飾器方式來使用rest框架,django_rest_frame實現(xiàn)權限管理都需要兩個東西的配合: authentication_classespermission_classes

# 方式1: 裝飾器
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import AllowAny
from rest_framework.response import Response


@api_view(["GET", ])
@permission_classes([AllowAny,])
@authentication_classes([SessionAuthentication, BasicAuthentication])
def test_example(request):
 content = {
   'user': unicode(request.user), # `django.contrib.auth.User` instance.
   'auth': unicode(request.auth), # None
  }
  return Response(content)

# ------------------------------------------------------------
# 方式2: 類
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
 authentication_classes = (SessionAuthentication, BasicAuthentication)
 permission_classes = (AllowAny,)

 def get(self, request, format=None):
  content = {
   'user': unicode(request.user), # `django.contrib.auth.User` instance.
   'auth': unicode(request.auth), # None
  }
  return Response(content)

上面給出的是權限配置的默認方案,寫和不寫沒有區(qū)別。 rest框架有自己的settings文件 ,最原始的默認值都可以在里面找到:

Django-Rest-Framework權限管理源碼的示例分析

說道rest的settings文件,要覆蓋其中的默認行為,特別是權限認證行為,我們只需要在 項目settings文件

中指定你自己的類即可:

REST_FRAMEWORK = {
 ...
 'DEFAULT_AUTHENTICATION_CLASSES': (
  'your_authentication_class_path',
 ),
 ...
}

在rest的settings文件中,獲取屬性時,會優(yōu)先加載項目的settings文件中的設置,如果項目中沒有的,才加載自己的默認設置:

初始化api_settings對象

api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)

APISettings 類中獲取屬性時優(yōu)先獲取項目的settings文件中 REST_FRAMEWORK 對象的值,沒有的再找自己的默認值

@property
def user_settings(self):
 if not hasattr(self, '_user_settings'):
  # _user_settings默認為加載項目settings文件中的REST_FRAMEWORK對象
  self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
 return self._user_settings

def __getattr__(self, attr):
 if attr not in self.defaults:
  raise AttributeError("Invalid API setting: '%s'" % attr)

 try:
  # Check if present in user settings
  # 優(yōu)先加載user_settings,即項目的settings文件,沒有就用默認
  val = self.user_settings[attr]
 except KeyError:
  # Fall back to defaults
  val = self.defaults[attr]

 # Coerce import strings into classes
 if attr in self.import_strings:
  val = perform_import(val, attr)

 # Cache the result
 self._cached_attrs.add(attr)
 setattr(self, attr, val)
 return val

在rest中settings中,能自動檢測 項目settings 的改變,并重新加載自己的配置文件:

Django-Rest-Framework權限管理源碼的示例分析

權限管理原理淺析

rest框架是如何使用 authentication_classespermission_classes ,并將二者配合起來進行權限管理的呢?

使用類方式實現(xiàn)的時候,我們都會直接或間接的使用到rest框架中的APIVIEW,在 urls.py 中使用該類的 as_view 方法來構建router

# views.py
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated


class ExampleAPIView(APIView):
 permission_classes = (IsAuthenticated,)
 ...
 
# -----------------------------
from django.conf.urls import url, include

from .views import ExampleAPIView

urlpatterns = [
 url(r'^example/(?P<example_id>[-\w]+)/examples/?$',
  ExampleAPIView.as_view()),
]

在我們調用 APIVIEW.as_view() 的時候,該類會調用父類的同名方法:

Django-Rest-Framework權限管理源碼的示例分析

父類的同名方法中,調用了dispatch方法:

Django-Rest-Framework權限管理源碼的示例分析

rest 重寫 了該方法,在該方法中對requset做了一次服務端初始化(加入驗證信息等)處理

Django-Rest-Framework權限管理源碼的示例分析

調用權限管理

Django-Rest-Framework權限管理源碼的示例分析

在權限管理中會使用默認的或是你指定的權限認證進行驗證: 這里只是做驗證并存儲驗證結果 ,這里操作完后authentication_classes的作用就完成了。驗證結果會在后面指定的 permission_classes 中使用!

def get_authenticators(self):
  """
  Instantiates and returns the list of authenticators that this view can use.
  """
  return [auth() for auth in self.authentication_classes]

通過指定的permission_classes確定是否有當前接口的訪問權限:

class IsAuthenticatedOrReadOnly(BasePermission):
 """
 The request is authenticated as a user, or is a read-only request.
 """

 def has_permission(self, request, view):
  return (
   request.method in SAFE_METHODS or
   request.user and
   request.user.is_authenticated
  )

最后,不管有沒有使用permission_classes來決定是否能訪問,默認的或是你自己指定的authentication_classes都會執(zhí)行并將權限結果放在request中!

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Django-Rest-Framework權限管理源碼的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,更多相關知識等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI