Django-Rest-Framework 權(quán)限管理源碼淺析(小結(jié))
在django的views中不論是用類方式還是用裝飾器方式來(lái)使用rest框架,django_rest_frame實(shí)現(xiàn)權(quán)限管理都需要兩個(gè)東西的配合: authentication_classes 和 permission_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)
上面給出的是權(quán)限配置的默認(rèn)方案,寫和不寫沒有區(qū)別。 rest框架有自己的settings文件 ,最原始的默認(rèn)值都可以在里面找到:

說(shuō)道rest的settings文件,要覆蓋其中的默認(rèn)行為,特別是權(quán)限認(rèn)證行為,我們只需要在 項(xiàng)目settings文件
中指定你自己的類即可:
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
'your_authentication_class_path',
),
...
}
在rest的settings文件中,獲取屬性時(shí),會(huì)優(yōu)先加載項(xiàng)目的settings文件中的設(shè)置,如果項(xiàng)目中沒有的,才加載自己的默認(rèn)設(shè)置:
初始化api_settings對(duì)象
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
APISettings 類中獲取屬性時(shí)優(yōu)先獲取項(xiàng)目的settings文件中 REST_FRAMEWORK 對(duì)象的值,沒有的再找自己的默認(rèn)值
@property
def user_settings(self):
if not hasattr(self, '_user_settings'):
# _user_settings默認(rèn)為加載項(xiàng)目settings文件中的REST_FRAMEWORK對(duì)象
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,即項(xiàng)目的settings文件,沒有就用默認(rèn)
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中,能自動(dòng)檢測(cè) 項(xiàng)目settings 的改變,并重新加載自己的配置文件:

權(quán)限管理原理淺析
rest框架是如何使用 authentication_classes 和 permission_classes ,并將二者配合起來(lái)進(jìn)行權(quán)限管理的呢?
使用類方式實(shí)現(xiàn)的時(shí)候,我們都會(huì)直接或間接的使用到rest框架中的APIVIEW,在 urls.py 中使用該類的 as_view 方法來(lái)構(gòu)建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()), ]
在我們調(diào)用 APIVIEW.as_view() 的時(shí)候,該類會(huì)調(diào)用父類的同名方法:

父類的同名方法中,調(diào)用了dispatch方法:

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

調(diào)用權(quán)限管理

在權(quán)限管理中會(huì)使用默認(rèn)的或是你指定的權(quán)限認(rèn)證進(jìn)行驗(yàn)證: 這里只是做驗(yàn)證并存儲(chǔ)驗(yàn)證結(jié)果 ,這里操作完后authentication_classes的作用就完成了。驗(yàn)證結(jié)果會(huì)在后面指定的 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]
通過(guò)指定的permission_classes確定是否有當(dāng)前接口的訪問權(quán)限:
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來(lái)決定是否能訪問,默認(rèn)的或是你自己指定的authentication_classes都會(huì)執(zhí)行并將權(quán)限結(jié)果放在request中!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用celery和Django處理異步任務(wù)的流程分析
Celery是 一個(gè)專注于實(shí)時(shí)處理的任務(wù)隊(duì)列,它還支持任務(wù)調(diào)度。 Celery快速,簡(jiǎn)單,高度可用且靈活。這篇文章主要介紹了使用celery和Django處理異步任務(wù)的流程分析,需要的朋友可以參考下2020-02-02
pytorch實(shí)現(xiàn)mnist分類的示例講解
今天小編就為大家分享一篇pytorch實(shí)現(xiàn)mnist分類的示例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-01-01
python Pandas庫(kù)基礎(chǔ)分析之時(shí)間序列的處理詳解
這篇文章主要介紹了python Pandas庫(kù)基礎(chǔ)分析之時(shí)間序列的處理詳解,Pandas作為Python環(huán)境下的數(shù)據(jù)分析庫(kù),更是提供了強(qiáng)大的日期數(shù)據(jù)處理的功能,是處理時(shí)間序列的利器,需要的朋友可以參考下2019-07-07
python獲取redis memory使用情況場(chǎng)景分析
這篇文章主要介紹了python獲取redis memory使用情況,項(xiàng)目研發(fā)過(guò)程中,用到Python操作Redis場(chǎng)景,記錄學(xué)習(xí)過(guò)程中的心得體會(huì),需要的朋友可以參考下2022-12-12
linux安裝python修改默認(rèn)python版本方法
在本文中我們給大家總結(jié)了關(guān)于linux安裝python修改默認(rèn)python版本的方法和相關(guān)知識(shí)點(diǎn),需要的讀者們參考下。2019-03-03
Python 實(shí)現(xiàn)還原已撤回的微信消息
這篇文章主要介紹了Python 神操作,還原已撤回的微信消息功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06
利用Anaconda創(chuàng)建虛擬環(huán)境的全過(guò)程
因?yàn)槎啻沃匦屡渲铆h(huán)境,這些命令每次都要用,每次都忘記,需要重新搜索,所以記錄這一過(guò)程,下面這篇文章主要給大家介紹了關(guān)于利用Anaconda創(chuàng)建虛擬環(huán)境的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
Python字符串的15個(gè)基本操作(小結(jié))
這篇文章主要介紹了Python字符串的15個(gè)基本操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02

