跳到主要内容

Django REST 认证

介绍

在构建 Web API 时,认证(Authentication)是一个至关重要的环节。它确保只有经过验证的用户才能访问受保护的资源。Django REST 框架(DRF)提供了多种认证方式,帮助开发者轻松实现 API 的安全性。

本文将介绍 Django REST 框架中的认证机制,包括基本认证、Token 认证、Session 认证以及自定义认证。我们将通过代码示例和实际案例,帮助你理解并实现这些认证方式。

基本概念

在 Django REST 框架中,认证是指验证用户身份的过程。认证机制通常与权限(Permissions)结合使用,以确保用户只能访问他们有权限的资源。

DRF 提供了以下几种常见的认证方式:

  1. 基本认证(Basic Authentication):使用 HTTP 基本认证,通过用户名和密码进行验证。
  2. Token 认证(Token Authentication):使用 Token 进行身份验证,通常用于无状态 API。
  3. Session 认证(Session Authentication):使用 Django 的会话机制进行认证,适用于有状态的 Web 应用。
  4. 自定义认证(Custom Authentication):开发者可以根据需求实现自定义的认证逻辑。

基本认证

基本认证是最简单的认证方式,它通过 HTTP 请求头中的 Authorization 字段传递用户名和密码。虽然这种方式易于实现,但由于密码以明文形式传输,安全性较低,通常仅用于测试环境。

代码示例

首先,在 settings.py 中启用基本认证:

python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
],
}

然后,在视图类中使用 @authentication_classes@permission_classes 装饰器来限制访问:

python
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ProtectedView(APIView):
authentication_classes = [BasicAuthentication]
permission_classes = [IsAuthenticated]

def get(self, request):
return Response({"message": "You are authenticated!"})

输入与输出

当你访问 /protected/ 时,如果没有提供有效的用户名和密码,DRF 将返回 401 Unauthorized 响应。如果提供了正确的凭据,你将看到以下输出:

json
{
"message": "You are authenticated!"
}

Token 认证

Token 认证是一种常见的无状态认证方式,适用于前后端分离的应用。用户首次登录时,服务器生成一个 Token 并返回给客户端。客户端在后续请求中通过 Authorization 头携带该 Token 进行身份验证。

代码示例

首先,安装 djangorestframework-simplejwt 包:

bash
pip install djangorestframework-simplejwt

然后,在 settings.py 中配置 Token 认证:

python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}

接下来,创建用户登录视图以生成 Token:

python
from rest_framework_simplejwt.views import TokenObtainPairView

class LoginView(TokenObtainPairView):
pass

最后,在受保护的视图中使用 Token 认证:

python
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ProtectedView(APIView):
permission_classes = [IsAuthenticated]

def get(self, request):
return Response({"message": "You are authenticated with Token!"})

输入与输出

用户登录时,客户端发送用户名和密码,服务器返回 Token:

json
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

客户端在后续请求中携带 Token:

http
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

如果 Token 有效,服务器将返回受保护资源:

json
{
"message": "You are authenticated with Token!"
}

Session 认证

Session 认证基于 Django 的会话机制,适用于传统的 Web 应用。用户在登录后,服务器会创建一个会话,并将会话 ID 存储在客户端的 Cookie 中。

代码示例

settings.py 中启用 Session 认证:

python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
],
}

然后,在视图类中使用 Session 认证:

python
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ProtectedView(APIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]

def get(self, request):
return Response({"message": "You are authenticated with Session!"})

输入与输出

用户登录后,服务器会创建一个会话,并将会话 ID 存储在 Cookie 中。客户端在后续请求中自动携带该 Cookie,服务器验证会话 ID 后返回受保护资源:

json
{
"message": "You are authenticated with Session!"
}

自定义认证

如果内置的认证方式无法满足需求,你可以实现自定义认证。自定义认证类需要继承 BaseAuthentication,并实现 authenticate 方法。

代码示例

以下是一个简单的自定义认证示例,基于请求头中的自定义 Token 进行认证:

python
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

class CustomTokenAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.META.get('HTTP_X_CUSTOM_TOKEN')
if not token:
return None
if token != 'SECRET_TOKEN':
raise AuthenticationFailed('Invalid token')
return (None, None) # 返回 (user, auth) 元组

settings.py 中启用自定义认证:

python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'path.to.CustomTokenAuthentication',
],
}

输入与输出

客户端在请求头中携带自定义 Token:

http
X-Custom-Token: SECRET_TOKEN

如果 Token 有效,服务器将返回受保护资源:

json
{
"message": "You are authenticated with Custom Token!"
}

实际案例

假设你正在开发一个任务管理应用,用户需要登录后才能创建、查看和删除任务。你可以使用 Token 认证来保护任务相关的 API。

  1. 用户登录后获取 Token。
  2. 客户端在请求任务 API 时携带 Token。
  3. 服务器验证 Token 并返回任务数据。

总结

Django REST 框架提供了多种认证方式,开发者可以根据应用场景选择合适的认证机制。本文介绍了基本认证、Token 认证、Session 认证以及自定义认证,并提供了代码示例和实际案例。

附加资源与练习

  • 官方文档Django REST 框架认证
  • 练习:尝试实现一个自定义认证类,基于请求参数中的 API Key 进行认证。
  • 扩展阅读:了解 OAuth2 和 JWT 认证,探索更复杂的认证场景。

希望本文能帮助你掌握 Django REST 框架中的认证机制,为你的 API 提供安全保障!