Django-restframework 之 Authentication 實現方式
> 官方原文鏈接
納尼,你居然敢說看不懂???那就且聽在下拙見...
REST framework 的 Request
類擴展與標準的 HttpRequest
,並做了相應的增強,比如更加靈活的請求解析(request parsing)和認證(request authentication)。
認證(Authentication)
REST framework 提供了靈活的認證方式:
- 可以在 API 的不同部分使用不同的認證策略。
- 支持同時使用多個身份驗證策略。
- 提供與傳入請求關聯的用戶(user)和令牌(token)信息。
.user
request.user
通常會返回 django.contrib.auth.models.User
如果請求未經身份驗證,則 request.user
的默認值是 django.contrib.auth.models.AnonymousUser
的實例(就是匿名用戶)。
關於 .user
的更多內容,以後再說~
.auth
request.auth
返回任何附加的認證上下文(authentication context)。request.auth
的確切行為取決於正在使用的身份驗證策略,但它通常可能是請求經過身份驗證的令牌(token)實例。
如果請求未經身份驗證,或者沒有附加上下文(context),則 request.auth
的默認值為 None
關於 .auth
的更多內容,以後再說~
.authenticators
APIView
類或 @api_view
裝飾器將確保根據視圖上設置的 authentication_classes
或基於 settings
文件中的 DEFAULT_AUTHENTICATORS
設置將此屬性(.authenticators
)自動設置為 Authentication
實例列表。
通常不需要關註該屬性......
註意:調用
.user
或.auth
屬性時可能會引發WrappedAttributeError
異常。
這些錯誤源於 authenticator 作為一個標準的AttributeError
,為了防止它們被外部屬性訪問修改,有必要重新提升為不同的異常類型。Python 無法識別來自 authenticator 的AttributeError
,並會立即假定請求對象沒有.user
或.auth
屬性。authenticator 需要修復。
認證實現過程
下面是我總結的精簡流程:
django 的url請求對應一個視圖函數as_view函數,其中調用rest_framework/views.py中的dispatch函數,這個函數會根據request的請求方法,去調用我們在view對象中定義的對應的方法:
urlpatterns = [
url(
r"^test/?", testView.as_view(),
)]
testView是繼承APIView的View類:
class TestView(APIView):
authentication_classes = (
BasicAuthentication,
SessionAuthentication,
TokenAuthentication,
)
permission_classes = (
IsAuthenticated,
)
def get(self,request):
pass
如果是get請求會調用as_view中的dispatch方法,dispatch根據request.Method調用
對應的get的方法,url->視圖函數
權限認證是在dispatch中做的
self.as_view()
||
vv
def dispatch(request,*args,**kwargs):
||
VV
self.initial(request,*args,**kwargs):
||
VV
self.perform_authentication
self.check_permissions
self.check_throttles
驗證某個用戶:
perform_authentication(request)
request.user
request.user其實是一個@property函數
裏面有個self._authenticate()方法
_authenticate(self)方法中驗證用戶就是authenticator.authenticate(self)
**self.authenticators從哪裏來?**
就是從視圖函數中的authentication_classes中的來,關於對view控制的其他類都在rest_framework/views.py的APIView類中定義了。
在BasicAuthentication中必須實現authenticate方法,並且返回一個用戶,並賦值給request.user,這個request.user就是系統中進行用戶認證的user對象,後續的權限認證
就是通過該user為依據進行判斷是否有某個api的權限!
user = authenticate(**credentials)
||
vv
user = backend.authenticate(**credentials)
這個authenticate是django的authenticate方法:
||
vv
主要是去數據庫校驗數據,校驗結束!!!
接著執行self.check_permissions(self,request):
如果權限不通過,那麽會執行self.permission_denied,然後這個異常會在dispatch
函數中被捕捉,當做結果傳遞給response。
當一次授權通過後,再一次訪問這個API時,用戶名密碼從哪來?
cookie和session
多說幾句:
.authenticators
其實存的就是當前使用的認證器(authenticator)列表,打印出來大概是這樣:
[<rest_framework.authentication.SessionAuthentication object at 0x7f8ae4528710>, <rest_framework.authentication.BasicAuthentication object at 0x7f8ae45286d8>]
可以看到這裏使用的認證器(authenticator)包括 SessionAuthentication
和 BasicAuthentication
。
Django-restframework 之 Authentication 實現方式