DRF認證
阿新 • • 發佈:2021-06-11
認證的寫法
# 認證的實現 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 = []