如何使用Django REST框架實現令牌身份驗證

 在本教程中,您將學習如何使用Django REST框架(DRF)實現基於標記的身份驗證。令牌身份驗證的工作方式是將用戶名和密碼交換爲令牌,以便在所有後續請求中使用該令牌來標識服務器端的用戶。

1. 設置項目

  讓我們從頭開始。安裝Django和DRF:

pip install django
pip install djangorestframework

  新建一個項目

django-admin.py startproject myapi .

  進入項目目錄

cd myapi 

  啓動一個新的應用程序,命名爲core:

django-admin.py startapp core

  你的項目結構應該是這樣的:

myapi/
 |-- core/
 |    |-- migrations/
 |    |-- __init__.py
 |    |-- admin.py
 |    |-- apps.py
 |    |-- models.py
 |    |-- tests.py
 |    +-- views.py
 |-- __init__.py
 |-- settings.py
 |-- urls.py
 +-- wsgi.py
manage.py

  在settings.py模塊中,將您創建的應用程序core和安裝的rest_framework應用程序添加到INSTALLED_APPS:

myapi/settings.py
INSTALLED_APPS = [
    # Django Apps
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Third-Party Apps
    'rest_framework',

    # Local Apps (Your project's apps)
    'myapi.core',
]

  返回項目根目錄(manage.py腳本所在的文件夾),遷移數據庫:

python manage.py migrate

  讓我們創建我們的第一個API視圖來測試一下:

myapi/core/views.py
from rest_framework.views import APIView
from rest_framework.response import Response

class HelloView(APIView):
    def get(self, request):
        content = {'message': 'Hello, World!'}
        return Response(content)

  現在在url .py模塊中註冊一個路徑:

myapi/urls.py
from django.urls import path
from myapi.core import views

urlpatterns = [
    path('hello/', views.HelloView.as_view(), name='hello'),
]

  現在我們有了一個/hello/的API,我們可以執行GET請求。我們可以使用瀏覽器來使用這個端點,只需訪問URL http://127.0.0.1:8000/hello/
在這裏插入圖片描述
  我們還可以通過傳遞querystring中的格式參數(如http://127.0.0.1:8000/hello/?format= JSON)來請求接收作爲普通JSON數據的響應:
在這裏插入圖片描述
  這兩種方法都適合嘗試DRF API,但有時命令行工具更方便,因爲我們可以更輕鬆地處理請求頭。您可以使用curl,它在所有主要的Linux/macOS發行版上都廣泛可用

curl http://127.0.0.1:8000/hello/

在這裏插入圖片描述
  但通常我更喜歡使用HTTPie,這是一個非常棒的Python命令行工具:

http http://127.0.0.1:8000/hello/

在這裏插入圖片描述
  現在我們使用token來保護這個API端點,這樣我們就可以實現基於token的身份驗證:

myapi/core/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated  # <-- Here


class HelloView(APIView):
    permission_classes = (IsAuthenticated,)             # <-- And here

    def get(self, request):
        content = {'message': 'Hello, World!'}
        return Response(content)

  再次嘗試訪問API接口

http http://127.0.0.1:8000/hello/

在這裏插入圖片描述
  現在我們得到一個HTTP 403禁止錯誤。現在讓我們實現令牌身份驗證,以便訪問此端點。

2. 實現令牌身份驗證

  我們需要在settings.py模塊中添加兩條信息。第一個包括rest_framework.authtoken到你的INSTALLED_APPS,幷包含到REST_FRAMEWORKTokenAuthentication:

myapi/settings.py
INSTALLED_APPS = [
    # Django Apps
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Third-Party Apps
    'rest_framework',
    'rest_framework.authtoken',  # <-- Here

    # Local Apps (Your project's apps)
    'myapi.core',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',  # <-- And here
    ],
}

  遷移數據庫以創建表來存儲身份驗證令牌

python manage.py migrate

在這裏插入圖片描述
  現在我們需要一個用戶帳戶,讓我們創建一個使用manage.py命令行實用工具:

python manage.py createsuperuser --username vitor --email vitor@example.com

  生成令牌的最簡單方法(僅用於測試)是再次使用命令行實用工具:

python manage.py drf_create_token vitor

在這裏插入圖片描述
  這段信息,隨機字符串9054f7aa9305e012b3c2300408c3dfdf390fcddf是我們接下來要使用的身份驗證

  現在我們有了TokenAuthentication請求認證,讓我們嘗試向/hello/ 接口再次發出一個請求

http http://127.0.0.1:8000/hello/

在這裏插入圖片描述
  注意我們的API現在向客戶端提供請求信息是需要認證方法的。

  最後,讓我們使用我們的token!

http http://127.0.0.1:8000/hello/ 'Authorization: Token 9054f7aa9305e012b3c2300408c3dfdf390fcddf'

在這裏插入圖片描述
  差不多就是這樣。現在,對於所有後續請求,您應該包括頭部授權:Token 9054f7aa9305e012b3c2300408c3dfdf390fcddf

  格式看起來很奇怪,通常在如何設置這個標題上很容易混淆。這將取決於客戶端如何設置HTTP請求頭。

  如,如果我們使用curl,命令應該是這樣的:

curl http://127.0.0.1:8000/hello/ -H 'Authorization: Token 9054f7aa9305e012b3c2300408c3dfdf390fcddf'

  或者如果是python requests調用:

import requests

url = 'http://127.0.0.1:8000/hello/'
headers = {'Authorization': 'Token 9054f7aa9305e012b3c2300408c3dfdf390fcddf'}
r = requests.get(url, headers=headers)

用戶獲取Token

DRF爲用戶提供一個接口,以便使用用戶名和密碼請求身份驗證令牌,包括以下路由到urls.py模塊

myapi/urls.py
from django.urls import path
from rest_framework.authtoken.views import obtain_auth_token  # <-- Here
from myapi.core import views

urlpatterns = [
    path('hello/', views.HelloView.as_view(), name='hello'),
    path('api-token-auth/', obtain_auth_token, name='api_token_auth'),  # <-- And here
]

  現在我們有了一個全新的API接口,它是/api-token-auth/,讓我們先來看看

http http://127.0.0.1:8000/api-token-auth/

在這裏插入圖片描述
  它不處理GET請求。基本上它只是一個接收帶有usernamepassword的POST請求的視圖。

http post http://127.0.0.1:8000/api-token-auth/ username=vitor password=123

在這裏插入圖片描述
  響應體是與此特定用戶關聯的令牌,在此之後,您將存儲此令牌並將其應用於未來的請求中。

  如果這是一個Angular客戶端,你可以把令牌存儲在localStorage中,如果這是一個桌面CLI應用程序,你可以把它存儲在一個點文件中(即隱藏文件),放在用戶主目錄的一個文本文件中。

總結

  需要注意的是,默認的令牌實現有一些限制,比如每個用戶只有一個令牌,沒有爲令牌設置過期日期的內置方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章