路由、認證
阿新 • • 發佈:2020-07-21
目錄
路由、認證
路由
1 普通路由書寫 path('test/',views.TestAPIView.as_view()), re_path('test/(?P<pk>\d+)',views.TestDetailAPIView.as_view()), 2 檢視類繼承ViewSetMinxin的路由,對應的請求方式執行對應的方法 path('test2/',views.Test2View.as_view(actions={'get':'list','post':'create'})), re_path('test2/(?P<pk>\d+)',views.Test2DetailView.as_view(actions={'retrieve','put':'update','delete':'destory'})), 3 檢視類繼承ModelViewSet自動生成路由,只有繼承檢視集的可以自動生成路由 #匯入路由物件 from rest_framework.routers import SimpleRouter #例項化物件 router = SimpleRouter() #註冊 router.register('test',views.Test)#test不需要加斜槓了 #加入路由 urlpatterns += router.urls
認證
#認證的寫法 1 寫一個類,繼承BaseAuthentication,重寫authenticate,裡面寫邏輯,認證通過,返回兩個值,一個值最終給了Requet物件的user,認證失敗,拋異常:APIException或者AuthenticationFailed 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()
認證元件的完整使用
#utils下的app01_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): 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.utils.app_auth.MyAuthentication"] } #區域性配置,檢視方法上方加上 authentication_classes=[MyAuthentication] #區域性禁用,檢視方法上方加上 authentication_classes=[]