先後端分離djangorestframework——認證組件

 

 authentication

認證是幹嗎的已經不須要多說。而先後端未分離的認證基本是用cookie或者session,先後端分離的通常用token數據庫

 

全局認證 

先建立一個django項目,項目名爲drfversion,app名爲DRF,設置簡單的數據庫表,並遷移:django

model:後端

 

 

view:cookie

 

url:session

 

啓動項目,訪問測試,先建立一個用戶root,密碼123: app

 

 

 

 

 

寫入一個認證類,讀源碼可知,自定義的認證類必需要定義這個方法:前後端分離

 

 在項目根目錄建立一個utils文件夾,建立auth文件,定義一個認證類,必須繼承BaseAuthentication,注意個人代碼獲取token是經過url的條件而得,經過request.query_params獲取:

ide

 

一樣,要應用此認證類,讀源碼可知,須要在配置文件裏做以下配置:post

 

重啓項目測試:測試

第一次,沒有帶值

 

從數據庫中複製該token值再次測試:

跳轉到其餘網頁查看:

 

login登陸頁面也能夠:

可是按開發邏輯,登陸頁面不該該驗證token對吧?還沒登陸怎麼能有token呢?是吧,因此不帶token:

可是不帶token此時又提示必需要帶,因此這就是全局認證的弊端

 

 

 局部認證

先在配置文件裏註釋掉全局認證:

 

在視圖類裏導入自定義的認證類,在須要認證的視圖類添加一個類屬性 :authentication_classes = [自定義認證類名,] 

 

其餘都不用修改,啓動測試:

 

登陸頁面:

 

test頁面,不帶token:

test頁面,帶上token:

 

DRF自帶的認證類

看了源碼,其實還有不少DRF自帶的認證類,都在rest_framework.authentication裏面,也能夠根據需求直接選用DRF自帶的認證類

 

以上項目主要的代碼:

根url:

from django.contrib import admin
from django.urls import path, re_path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'auth/', include(('DRF.urls'))),
]

 

app下url:

from django.urls import path, re_path
from DRF.views import DemoView, LoginView, TestView

urlpatterns = [
    path(r'', DemoView.as_view()),
    re_path(r'^login/', LoginView.as_view()),
    re_path(r'^test/', TestView.as_view()),
]

 

view:

from rest_framework.views import APIView
from rest_framework.views import Response
from utils.auth import MyAuth
from DRF.models import User
import uuid

class DemoView(APIView):
    def get(self, request):
        return Response('簡單認證')

class LoginView(APIView):
    def get(self, request):
        return Response('請登陸,若是沒有帳號請建立')

    def post(self, request):
        user = request.data.get('user')
        pwd = request.data.get('pwd')
        token = uuid.uuid4()
        User.objects.create(user=user, pwd=pwd, token=token)
        return Response('建立用戶成功')


class TestView(APIView):
    authentication_classes = [MyAuth,]

    def get(self, request):
        return Response('認證測試')
View

 

model:

from django.db import models


# Create your models here.

class User(models.Model):
    user = models.CharField(max_length=32, verbose_name='用戶名', null=True, blank=True)
    pwd = models.CharField(max_length=32, verbose_name='密碼', null=True, blank=True)
    token = models.UUIDField()

 

auth:

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from DRF.models import User


class MyAuth(BaseAuthentication):
    def authenticate(self, request):
        # 認證token
        token = request.query_params.get('token')
        if not token:
            raise AuthenticationFailed('沒有攜帶token')
        user_obj = User.objects.filter(token=token)
        if not user_obj:
            raise AuthenticationFailed('非法用戶')
        return (user_obj, token)

 

settings:

REST_FRAMEWORK = {
    "DEFAULT_VERSIONING_CLASS": "utils.version.MyVersion",    
    "DEFAULT_VERSION": "v1",
    "ALLOWED_VERSIONS": "v1, v2",
    "VERSION_PARAM": "ver",
    # "DEFAULT_AUTHENTICATION_CLASSES": ["utils.auth.MyAuth", ]
}

 

 

 

總結

  • 自定義類,必須繼承DRF定義好的認證類,須要用什麼就繼承什麼,且根據繼承的類不一樣,必需要定義該基類裏明確規定須要的方法或者屬性
  • 全局認證直接在配置文件裏的REST_FRAMEWORK裏配置字段"DEFAULT_AUTHENTICATION_CLASSES": ["自定義認證類", ],配置全局認證即表示每一個頁面都要驗證
  • 局部認證直接在須要認證的視圖類添加屬性authentication_classes = [自定義認證類名,] 
  • 認證能夠再url添加條件參數,能夠再請求頭,能夠再請求體,根據認證類的認證類型,在認證時作不一樣的處理
相關文章
相關標籤/搜索