1. 程式人生 > 其它 >DRF認證

DRF認證

認證的寫法

# 認證的實現
    1 寫一個類,繼承BaseAuthentication,重寫authenticate,認證的邏輯寫在裡面,
        認證通過,返回兩個值,一個最終給了Request物件的user,
        認證失敗,拋異常:AuthenticationFailed或者APIException
    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()

認證元件的使用

# 寫一個認證類 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')

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

# 區域性使用,在檢視類上寫:
    authentication_classes = [MyAuthentication]
    
# 區域性禁用
    authentication_classes = []