1. 程式人生 > 其它 >drf 認證使用

drf 認證使用

2 認證

2.1 認證的寫法

# 認證的實現
	1 寫一個類,繼承BaseAuthentication,重寫authenticate,認證的邏輯寫在裡面,認證通過,返回兩個值,一個值最終給了Requet物件的user,認證失敗,拋異常:APIException或者AuthenticationFailed
    2 全域性使用,區域性使用

2.2 認證的原始碼分析

#1 APIVIew----》dispatch方法---》self.initial(request, *args, **kwargs)---->有認證,許可權,頻率
#2 只讀認證原始碼: self.perform_authentication(request)
#3 self.perform_authentication(request)就一句話:request.user,需要去drf的Request物件中找user屬性(方法) 
#4 Request類中的user方法,剛開始來,沒有_user,走 self._authenticate()

#5 核心,就是Request類的 _authenticate(self):
    def _authenticate(self):
        # 遍歷拿到一個個認證器,進行認證
        # self.authenticators配置的一堆認證類產生的認證類物件組成的 list
        #self.authenticators 你在檢視類中配置的一個個的認證類:authentication_classes=[認證類1,認證類2],物件的列表
        for authenticator in self.authenticators:
            try:
                # 認證器(物件)呼叫認證方法authenticate(認證類物件self, request請求物件)
                # 返回值:登陸的使用者與認證的資訊組成的 tuple
                # 該方法被try包裹,代表該方法會拋異常,拋異常就代表認證失敗
                user_auth_tuple = authenticator.authenticate(self) #注意這self是request物件
            except exceptions.APIException:
                self._not_authenticated()
                raise

            # 返回值的處理
            if user_auth_tuple is not None:
                self._authenticator = authenticator
                # 如何有返回值,就將 登陸使用者 與 登陸認證 分別儲存到 request.user、request.auth
                self.user, self.auth = user_auth_tuple
                return
        # 如果返回值user_auth_tuple為空,代表認證通過,但是沒有 登陸使用者 與 登陸認證資訊,代表遊客
        self._not_authenticated()

2.3 認證元件的使用

# 寫一個認證類 app_auth.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01.models import UserToken
class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 認證邏輯,如果認證通過,返回兩個值
        #如果認證失敗,丟擲AuthenticationFailed異常
        token=request.GET.get('token')
        if  token:
            user_token=UserToken.objects.filter(token=token).first()
            # 認證通過
            if user_token:
                return user_token.user,token
            else:
                raise AuthenticationFailed('認證失敗')
        else:
            raise AuthenticationFailed('請求地址中需要攜帶token')

# 可以有多個認證,從左到右依次執行
# 全域性使用,在setting.py中配置
REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
}
# 區域性使用,在檢視類上寫
authentication_classes=[MyAuthentication]
# 區域性禁用
authentication_classes=[]