1. 程式人生 > 實用技巧 >路由、認證

路由、認證

目錄

路由、認證

路由

	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=[]