用Django全棧開發(fā)(進(jìn)階篇)——11. Django REST framework實(shí)現(xiàn)Token驗(yàn)證

大家好,這是皮爺給大家?guī)淼淖钚碌膶W(xué)習(xí)Python能干啥?之Django教程的進(jìn)階版。

很抱歉這篇文章更新的晚了,原因是皮爺這段時(shí)間一直在日本換工作,經(jīng)過一個(gè)月的煎熬,最后終于拿到了想要去的公司的offer。以后可以將peekpa.com和工作相結(jié)合,創(chuàng)建更加牛逼的peekpa.com 同時(shí)為大家制作更加詳細(xì)的,有內(nèi)容的教程。

在之前《用Django全棧開發(fā)》系列專輯里面,皮爺詳細(xì)的闡述了如何編寫一個(gè)完整的網(wǎng)站,具體效果可以瀏覽線上網(wǎng)站:Peekpa.com

從進(jìn)階篇開始,每一篇文章都是干貨滿滿,干的不行。這一節(jié),我們來說:如何通過Django REST Framework來實(shí)現(xiàn)Token驗(yàn)證。為我們的前后端分離做最后的準(zhǔn)備

Peekpa.com的官方地址:http://peekpa.com

獲取整套教程源碼唯一途徑,關(guān)注『皮爺擼碼』,回復(fù)『peekpa.com』

皮爺?shù)拿恳黄恼?,都配置相?duì)應(yīng)的代碼。這篇文章的代碼對(duì)應(yīng)的Tag是“Advanced_11”。

title.jpeg

背景了解

我們這里所說的驗(yàn)證,英文實(shí)際是Authentication。為什么要提到這個(gè)?原因很簡(jiǎn)單,在未來我們前后端分離的程序中,當(dāng)我們前端登錄了后臺(tái)系統(tǒng)之后,隨后每一次發(fā)送的HTTP請(qǐng)求,我們都要想一個(gè)辦法來確認(rèn)這個(gè)HTTP請(qǐng)求正好是那個(gè)登錄過的人發(fā)送的,而不是中間黑客劫持或者偽造的,這樣,我們就需要讓HTTP請(qǐng)求在發(fā)送的過程中,攜帶一個(gè)驗(yàn)證身份的東西,這個(gè)驗(yàn)證身份的東西,就是我們今天所說的Token Authentication。

當(dāng)然,在實(shí)際的生產(chǎn)過程中,我們的驗(yàn)證方式其實(shí)有很多,但是這里我們就先拿來Django REST Framework提供的TokenAuthentication來試驗(yàn)一下。

相關(guān)的TokenAuthentication參考文檔,可以去查閱官方文檔:

https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication

我們這里想要驗(yàn)證的,當(dāng)然就是我們當(dāng)時(shí)前后端分離的數(shù)據(jù)中心頁面了。

集成Token Authentication

第一步,當(dāng)然是要修改我們的setting.py文件了。我們需要將以下內(nèi)容添加進(jìn)去:

INSTALLED_APPS = [
    ### ...先前內(nèi)容省略...
    'rest_framework.authtoken',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}

這里簡(jiǎn)單說明一下:

  • DEFAULT_AUTHENTICATION_CLASSES這個(gè)是:
  • DEFAULT_PERMISSION_CLASSES這個(gè)是:

然后,我們需要修改我們的User Model,即peekpauser/model.py文件里,我們需要添加以下內(nèi)容:

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

這里的功能就是,當(dāng)我們創(chuàng)建一個(gè)用戶的時(shí)候,我們就會(huì)創(chuàng)建自動(dòng)創(chuàng)建一個(gè)Token,并且這個(gè)Token關(guān)聯(lián)到這個(gè)用戶的。

既然我們修改了Model,而且我們也在INSTALLED_APPS里面也添加了新的rest_framework.authtoken,那么我們接下來就要執(zhí)行python manage.py makemigrationspython manage.py migrate了,執(zhí)行完成,我們會(huì)在數(shù)據(jù)庫中生成Authon Token的表格:

001

接下來一步,我們?cè)?code>peekpauser目錄下,創(chuàng)建一個(gè)admin.py文件,并將下面的代碼放進(jìn)去:

from django.contrib import admin
from .models import User

class PeekpaUserAdmin(admin.ModelAdmin):
    pass
admin.site.register(User, PeekpaUserAdmin)

這樣做的目的是在我們的Django自帶的Admin頁面里面,將PeekpaUser加入進(jìn)去。

添加完了之后,我們啟動(dòng)程序。并且來到http://127.0.0.1:8000/admin/頁面,通過超級(jí)管理員賬號(hào)登錄進(jìn)來:

002

看到這里有三個(gè)內(nèi)容:Tokens, Users和 Groups。

我們這里需要使用到的就是Tokens和Users。

我們可以在回到我們之前寫好的Dashboard頁面http://127.0.0.1:8000/cms/dashboard/,然后在User里面創(chuàng)建一個(gè)新的User:

003

004

我們這里只是為了測(cè)試,所以簡(jiǎn)單一點(diǎn):賬號(hào):pylm@peekpa.com,密碼:peekpa。然后點(diǎn)擊確定。

創(chuàng)建好之后,我們?cè)倩氐轿覀兊腁dmin頁面,來看一下發(fā)生了什么。首先進(jìn)入U(xiǎn)ser頁面:

005

看到新創(chuàng)建的pylm@peekpa.com是成功創(chuàng)建出來的;接著我們?nèi)タ匆幌耇oken頁面:

006

看到這里,在創(chuàng)建新用戶的時(shí)候,系統(tǒng)自動(dòng)生成了一個(gè)與之匹配的Token,值為0db104f47f1fec1d4f179a6ca369b691c060848c,并且關(guān)聯(lián)到的User是我們剛剛創(chuàng)建的pylm@peekpa.com用戶。

這里就說明,我們的Token Authentication已經(jīng)完成了50%了,那么我們接著繼續(xù)。

使用Token Authentication

既然,我們要使用Token驗(yàn)證,首先第一步就是要拿到Token。

拿到Token有兩種方法:

  1. 用Django REST Framework自帶的obtain_auth_token方法可以獲取;
  2. 就是自己寫一個(gè)方法,在登錄成功的時(shí)候,將Token吐給前端出來。

我們這里就先使用第一種方法來給大家展示一下,咱們先把流程都跑通了,再優(yōu)化。

首先,我們需要將函數(shù)路徑修改一下,映射到obtain_auth_token方法中,直接修改Peekpa/urls.py文件里面,添加一下代碼:

from rest_framework.authtoken.views import obtain_auth_token

urlpatterns = [
    ### ...先前內(nèi)容過多,省略...
    path('api-auth/', obtain_auth_token)
]

這個(gè)obtain_auth_token方法只接受POST請(qǐng)求,需要傳入登錄賬號(hào)的參數(shù),即emailpassword這兩個(gè)。所以我們打開我們的Postman來測(cè)試一下:

007

看到,方法是POST,路徑是http://127.0.0.1:8000/api-token/,傳入兩個(gè)參數(shù)emailpassword,返回結(jié)果則是我們的Token,就是之前所生成的對(duì)應(yīng)pylm@peekpa.com這個(gè)賬號(hào)的token:0db104f47f1fec1d4f179a6ca369b691c060848c

這里如果傳入的參數(shù)不對(duì),則會(huì)返回其他錯(cuò)誤信息,這個(gè)大家可以下去自行試驗(yàn)一下。

接下來,我們就是要如何使用這個(gè)Token了。

我們的試想,是要通過上一節(jié)所講的數(shù)據(jù)中心異步請(qǐng)求接口,通過傳入?yún)?shù)以及Token,來給我們返回結(jié)果。那么我們就這么干。

如果想要在視圖函數(shù)里面使用Token的驗(yàn)證,我們需要稍微修改一下視圖函數(shù)。上節(jié)課我們寫的API函數(shù)是CenterApiView,對(duì)應(yīng)的URL是center/data/,在沒有修改之前,我們的接口http://127.0.0.1:8000/center/data/返回結(jié)果是這一個(gè)樣子:

008

為了融合Token,我們這里就把CenterApiView稍微修改一下:

from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication

class CenterApiView(APIView):
    authentication_classes = [TokenAuthentication]
    permission_classes = (IsAuthenticated,)

然后我們來在Postman里面測(cè)試一下我們的接口http://127.0.0.1:8000/center/data/,發(fā)現(xiàn)返回結(jié)果是未授權(quán):

009

但是,如果想要我們的接口通過Token驗(yàn)證,我們就需要在請(qǐng)求HEADER里面添加一個(gè)變量:Authorization,他的值是我們剛才的Token。我們這個(gè)時(shí)候添加了參數(shù)再來看一下:

010

要注意這里Authorization的值,是Token再加一個(gè)空格,然后再跟值。

如果我們這個(gè)時(shí)候,把Authorization的值修改一下,將最后的c換乘d,看看返回結(jié)果:

011

直接返回的401錯(cuò)誤。

關(guān)于在視圖函數(shù)添加權(quán)限,我們還可以在Peekpa/settings.py里面添加下面的內(nèi)容:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}

不過這么做的話,就是全局設(shè)置了驗(yàn)證類和驗(yàn)證權(quán)限了。

這樣,我們的Token驗(yàn)證邏輯就完全跑通了。接下來,我們就能夠通過這種方式來給前后端分離做準(zhǔn)備了,即VUE前端的每次請(qǐng)求,都可以攜帶Token來獲取數(shù)據(jù)。

當(dāng)然,這里的驗(yàn)證,并不僅僅只是Token這種方式,還有其他很多種,這里皮爺僅僅只是拋磚引玉,為大家打開一個(gè)思路。

目前,peekpa.com的代碼,我已經(jīng)在Github和碼云上面共享了,每一篇文章都配有源碼。接下來的內(nèi)容,將會(huì)是重磅的前后端分離,前端Vue開發(fā),后端Django開發(fā)。

技術(shù)總結(jié)

最后總結(jié)一下,

Django REST framework實(shí)現(xiàn)Token驗(yàn)證:

  1. setting.py文件里面的INSTALLED_APPS里添加rest_framework.authtoken;
  2. 加了INSTALLED_APPS之后,需要執(zhí)行python manage.py makemigrationspython manage.py
  3. 修改User模型,在創(chuàng)建用戶的時(shí)候,通過Token.objects.create(user=instance)創(chuàng)建一個(gè)和User相關(guān)聯(lián)的Token;
  4. 在需要使用Token驗(yàn)證的視圖函數(shù)中,添加authentication_classespermission_classes;
  5. 進(jìn)階篇的Django Token驗(yàn)證總結(jié)完畢。

獲取整套教程源碼唯一途徑,關(guān)注『皮爺擼碼』,回復(fù)『peekpa.com』

長(zhǎng)按下圖二維碼關(guān)注,如文章對(duì)你有啟發(fā)或者能夠幫助到你,歡迎點(diǎn)贊,在看,轉(zhuǎn)發(fā)三連走一發(fā),這是對(duì)我原創(chuàng)內(nèi)容輸出的最大肯定。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容