1. 程式人生 > >Django-restframework 之 Authentication 實現方式

Django-restframework 之 Authentication 實現方式

定義 sts 增強 sse 不同的 標準 根據 att 識別

> 官方原文鏈接

納尼,你居然敢說看不懂???那就且聽在下拙見...

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)包括 SessionAuthenticationBasicAuthentication

Django-restframework 之 Authentication 實現方式