如何使用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应用程序,你可以把它存储在一个点文件中(即隐藏文件),放在用户主目录的一个文本文件中。

总结

  需要注意的是,默认的令牌实现有一些限制,比如每个用户只有一个令牌,没有为令牌设置过期日期的内置方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值