在现代 Web 开发中,API 接口扮演着至关重要的角色。它们是不同系统之间进行数据交互的桥梁。Django REST framework (DRF) 是一款强大且灵活的工具,可以帮助我们快速构建 RESTful API。结合 JSON Web Tokens (JWT) 可以实现安全的身份验证。本文将一步步指导你如何使用 DRF 和 JWT 构建 API 接口,并考虑到 API 的版本控制、文档生成和安全性。
1. 环境搭建与依赖安装
首先,确保你已经安装了 Python 和 pip。推荐使用 virtualenv 或 conda 创建一个独立的虚拟环境,以避免依赖冲突。
# 创建虚拟环境 (virtualenv)
python -m venv venv
# 激活虚拟环境
# Linux/macOS
source venv/bin/activate
# Windows
.\venv\Scripts\activate
# 安装 Django 和 Django REST framework
pip install django djangorestframework
# 安装 JWT 相关依赖
pip install djangorestframework-simplejwt
2. 创建 Django 项目和应用
创建一个 Django 项目和一个用于 API 的应用。
# 创建 Django 项目
django-admin startproject myapi
cd myapi
# 创建 API 应用
python manage.py startapp api
将 api
应用添加到 myapi/settings.py
的 INSTALLED_APPS
中:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'api',
]
3. 配置 Django REST framework 和 JWT
在 myapi/settings.py
中配置 DRF 和 JWT:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
}
解释:
DEFAULT_PERMISSION_CLASSES
: 设置默认的权限类,这里设置为IsAuthenticated
,表示只有认证用户才能访问 API。DEFAULT_AUTHENTICATION_CLASSES
: 设置默认的认证类,这里设置为JWTAuthentication
,使用 JWT 进行身份验证。DEFAULT_VERSIONING_CLASS
: 设置API版本控制类,这里设置为URLPathVersioning
,通过 URL 路径进行版本控制。SIMPLE_JWT
: 配置 JWT 的各项参数,例如 access token 和 refresh token 的过期时间、签名算法等。
4. 创建模型 (Model)
假设我们要创建一个简单的 Product
模型,在 api/models.py
中定义:
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
执行数据库迁移:
python manage.py makemigrations
python manage.py migrate
5. 创建序列化器 (Serializer)
序列化器用于将模型数据转换为 JSON 格式,以及将 JSON 数据转换为模型实例。在 api/serializers.py
中创建 ProductSerializer
:
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
6. 创建视图 (View)
视图处理 API 请求并返回响应。在 api/views.py
中创建 ProductViewSet
:
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
from rest_framework.permissions import IsAuthenticated
from rest_framework.versioning import URLPathVersioning
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
permission_classes = [IsAuthenticated]
versioning_class = URLPathVersioning
解释:
viewsets.ModelViewSet
: 提供了一组默认的 API 操作,例如创建、读取、更新和删除。queryset
: 指定要查询的模型数据。serializer_class
: 指定要使用的序列化器。permission_classes
: 指定权限类,这里使用IsAuthenticated
,确保只有认证用户才能访问。versioning_class
: 指定版本控制类,与 settings.py 保持一致
7. 配置 URL
在 api/urls.py
中配置 API 的 URL:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register(r'products', views.ProductViewSet, basename='product')
urlpatterns = [
path('', include(router.urls)),
]
在 myapi/urls.py
中包含 api
应用的 URL,并添加 JWT 的 token 获取和刷新 endpoint:
from django.urls import path, include
from rest_framework_simplejwt.views import (TokenObtainPairView,TokenRefreshView,)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('api.urls')),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
重要: 注意api/v1/
,这里体现了API的版本控制,后续升级API只需修改版本号,即可保证旧版本API的正常使用。
8. JWT 身份验证
获取 Token
首先,你需要创建一个用户,可以通过 Django 的 createsuperuser
命令创建超级用户,也可以在 api/serializers.py
中创建用户注册的序列化器和视图。
创建用户后,可以使用 TokenObtainPairView
获取 JWT token。发送 POST 请求到 /api/token/
,携带 username
和 password
:
{
"username": "your_username",
"password": "your_password"
}
成功后,你会收到包含 access
token 和 refresh
token 的响应:
{
"access": "...",
"refresh": "..."
}
使用 Token
在访问受保护的 API 接口时,需要在请求头中添加 Authorization
字段,值为 Bearer <access_token>
。例如:
Authorization: Bearer <your_access_token>
刷新 Token
当 access
token 过期后,可以使用 refresh
token 刷新。发送 POST 请求到 /api/token/refresh/
,携带 refresh
token:
{
"refresh": "..."
}
成功后,你会收到新的 access
token:
{
"access": "..."
}
9. API 版本控制
DRF 提供了多种版本控制方案,例如:
- URL 路径版本控制 (URLPathVersioning): 如上例所示,在 URL 中包含版本号,例如
/api/v1/products/
。 - 查询参数版本控制 (QueryParameterVersioning): 通过查询参数指定版本,例如
/api/products/?version=v1
。 - Header 版本控制 (AcceptHeaderVersioning): 通过
Accept
header 指定版本。
选择适合你项目的版本控制方案,并在 settings.py
中配置 DEFAULT_VERSIONING_CLASS
。
10. API 文档生成
可以使用 drf-spectacular
或 drf-yasg
等工具自动生成 API 文档。
使用 drf-spectacular
pip install drf-spectacular
在 settings.py
中添加 drf_spectacular
到 INSTALLED_APPS
:
INSTALLED_APPS = [
...
'drf_spectacular',
]
在 urls.py
中添加 schema 的 URL:
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
urlpatterns = [
...
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
# Optional UI:
path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
]
现在,你可以通过 /api/schema/swagger-ui/
或 /api/schema/redoc/
访问 API 文档。
11. 安全性注意事项
- 使用 HTTPS: 确保你的 API 使用 HTTPS 协议,以加密数据传输。
- 验证所有输入: 对所有输入数据进行验证,以防止 SQL 注入、XSS 等攻击。
- 限制请求频率: 使用 throttling 限制 API 请求频率,以防止 DDoS 攻击。
- 保护敏感数据: 不要在 API 响应中返回敏感数据,例如密码、信用卡信息等。
- 定期更新依赖: 定期更新 Django、DRF 和其他依赖库,以修复安全漏洞。
- CORS配置: 配置CORS (Cross-Origin Resource Sharing),允许特定的域名访问你的API,防止跨域攻击。在settings.py中配置:
INSTALLED_APPS = [ ... 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', ... ] CORS_ALLOWED_ORIGINS = [ "https://example.com", "http://localhost:8080", ]
12. 总结
本文详细介绍了如何使用 Django REST framework 和 JWT 构建安全的 API 接口,并考虑了 API 的版本控制、文档生成和安全性。希望本文能够帮助你快速上手并构建高质量的 API。当然,实际开发中还需要根据具体需求进行调整和优化。记住,安全永远是第一位的!