Django 后端架构开发:JWT 项目实践与Drf版本控制

简介: Django 后端架构开发:JWT 项目实践与Drf版本控制

🛠️ Django 后端架构开发:JWT 项目实践与Drf版本控制

📌 JWT 项目实践:从理论到实战

JSON Web Token(JWT)是当前最流行的身份认证机制之一,在后端开发中被广泛使用。它基于Token的身份验证方式,避免了传统的Session认证在分布式系统中的局限性。在本节中,我们将通过一个实际的Django项目,详细解析JWT的应用场景和实现方式。

首先,在Django中使用JWT进行用户认证时,通常需要借助第三方库,如 djangorestframework-jwtdjango-rest-framework-simplejwt。这些库提供了方便的工具和方法,帮助我们在Django REST Framework中集成JWT。

以下是一个简单的项目示例,我们将逐步解析其中的关键代码。

# settings.py 配置
INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework_simplejwt',
]
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}
# 配置JWT的过期时间等参数
SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': True,
    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUTH_HEADER_TYPES': ('Bearer',),
    ...
}

settings.py 中,我们配置了JWT的认证方式,并设置了相关参数。ACCESS_TOKEN_LIFETIME 是访问令牌的有效时间,而 REFRESH_TOKEN_LIFETIME 则决定了刷新令牌的有效期。这些参数的设置直接影响了系统的安全性和用户体验。

接下来,我们在 views.py 中实现JWT的登录逻辑。

from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
@api_view(['POST'])
def login(request):
    """
    用户登录视图,使用JWT进行身份验证
    """
    serializer = TokenObtainPairView.as_view()(request._request).data
    return Response(serializer)
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def logout(request):
    """
    用户注销视图,废弃当前的Refresh Token
    """
    try:
        token = request.data['refresh']
        token_obj = RefreshToken(token)
        token_obj.blacklist()
        return Response({'message': '注销成功'}, status=200)
    except Exception as e:
        return Response({'error': str(e)}, status=400)

在这个示例中,我们创建了 loginlogout 视图。login 视图通过 TokenObtainPairView 生成访问令牌和刷新令牌,logout 视图则通过黑名单机制废弃用户的刷新令牌,确保其后续的请求失效。

通过这种方式,我们实现了一个基于JWT的完整认证流程,并且支持令牌的手动废弃,提升了系统的安全性。

📌 JWT 使用方式和特点:灵活且高效的认证机制

JWT的全称是JSON Web Token,是一种开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式用于通信双方之间以JSON对象的形式传递信息。该信息通过数字签名进行验证,从而确保数据的真实性与完整性。JWT的应用场景广泛,尤其在现代Web应用中,因其无状态、跨域支持等优点,广受欢迎。

与传统的Session认证机制不同,JWT的无状态性使其非常适合于微服务架构和分布式系统。在传统的Session认证中,服务器需要保存每个用户的Session数据,这在分布式环境下会带来很多挑战。而JWT的自包含性允许服务器不必保存会话状态,极大地减轻了服务器的负担。

JWT的结构包括三部分:头部(Header)、载荷(Payload)和签名(Signature)。

  • 头部:头部通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法(如HMAC SHA256或RSA)。
{
  "alg": "HS256",
  "typ": "JWT"
}
  • 载荷:载荷部分包含声明(claims),声明是一些实体(通常是用户)的状态信息。声明可以分为三类:注册声明(如 issexpsub)、公共声明和私有声明。
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
  • 签名:签名是将头部、载荷和一个密钥进行编码后生成的。签名部分是保证JWT数据完整性的重要手段,只有拥有密钥的一方才能生成或验证签名。

JWT的使用方式非常简单,通常在用户登录时,服务器会生成一个JWT并返回给客户端,客户端将其保存在本地存储中。在后续的请求中,客户端将JWT放入HTTP请求头中,服务器通过验证JWT的签名来判断请求是否合法。

# 示例:在请求头中携带JWT
import requests
headers = {
    'Authorization': 'Bearer <your_jwt_token_here>',
}
response = requests.get('https://example.com/api/resource', headers=headers)

这种无状态的认证机制,使得JWT特别适合跨域认证以及微服务架构的系统。客户端不需要每次请求都与服务器进行会话状态的校验,极大地提升了系统的性能。

📌 REST Framework-JWT 介绍和使用:集成与扩展

Django REST Framework(DRF)提供了强大的身份验证机制,而 djangorestframework-jwtdjango-rest-framework-simplejwt 则进一步扩展了DRF,方便我们集成JWT。

rest_framework_simplejwt 是一个简单易用的JWT扩展库,它能够轻松地与DRF集成,并提供了丰富的配置选项和自定义功能。在本节中,我们将通过实际代码演示如何在DRF中集成JWT认证,并进行扩展以满足项目需求。

首先,我们在项目中安装并配置 rest_framework_simplejwt

pip install djangorestframework-simplejwt
• 1

安装完成后,我们在 settings.py 中进行配置,指定默认的认证类为 JWTAuthentication

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

接下来,我们创建自定义的视图和路由,以支持JWT的生成和刷新。

# urls.py 配置
from django.urls import path
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)
urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

在这个配置中,我们创建了两个路由,一个用于获取初始的访问令牌和刷新令牌,另一个用于刷新访问令牌。这种机制确保了令牌在过期后可以通过刷新令牌获取新的访问令牌,而不需要重新登录。

为了增强项目的安全性,我们还可以自定义 TokenObtainPairSerializer,以加入额外的用户信息到JWT载荷中。

# serializers.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)
        data['username'] = self.user.username
        data['email'] = self.user.email
        return data

然后在视图中使用我们自定义的序列化器。

from rest_framework_simplejwt.views import TokenObtainPairView
class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

通过这种方式,我们可以将更多的用户信息嵌入到JWT中,满足项目的具体需求。

📌 REST Framework 身份验证和权限管理:安全与灵活性的完美结合

在构建Web API时,身份验证和权限管理是不可忽视的重要环节。Django REST Framework(DRF)为我们提供了灵活且强大的身份验证与权限管理机制。通过合理配置和扩展,我们可以确保API的安全性,并实现精细化的权限控制。

1. 身份验证

在DRF中,身份验证是通过设置 DEFAULT_AUTHENTICATION_CLASSES 来实现的。常见的身份验证方式包括Session、Token、JWT等。在本节中,我们将重点讨论JWT的身份验证。

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES
': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

通过上述配置,DRF将使用JWT进行身份验证。每次API请求时,DRF会从请求头中提取JWT,并验证其有效性。若验证通过,则请求将继续处理,否则返回401未授权错误。

2. 权限管理

DRF的权限管理机制允许我们根据请求用户的身份、请求方法、请求资源等条件,精细控制访问权限。DRF提供了多种内置权限类,如 AllowAnyIsAuthenticatedIsAdminUserIsAuthenticatedOrReadOnly 等。

例如,我们可以使用 IsAuthenticated 权限类,确保只有经过身份验证的用户才能访问某些敏感资源。

from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response
class SecureAPIView(APIView):
    permission_classes = [IsAuthenticated]
    def get(self, request):
        return Response({'message': '只有认证用户可以看到这条信息'})

此外,我们还可以自定义权限类,以满足特定的业务需求。例如,我们可以创建一个 IsOwner 权限类,确保只有资源的所有者才能对其进行修改。

from rest_framework.permissions import BasePermission
class IsOwner(BasePermission):
    """
    只允许资源的所有者进行操作
    """
    def has_object_permission(self, request, view, obj):
        return obj.owner == request.user

在视图中,我们可以将自定义权限类与其他权限类组合使用,以实现复杂的权限控制逻辑。

class UserDetailAPIView(APIView):
    permission_classes = [IsAuthenticated, IsOwner]
    def get(self, request, pk):
        user = get_object_or_404(User, pk=pk)
        self.check_object_permissions(request, user)
        return Response({'username': user.username, 'email': user.email})

通过上述配置,我们可以确保只有资源所有者本人才能查看或修改其个人信息,提升了系统的安全性和用户体验。

📌 REST Framework 版本控制 - URLPathVersioning、QueryParameterVersioning 和 NamespaceVersioning:灵活应对API演化

在API开发中,随着业务的发展和用户需求的变化,API的版本控制变得尤为重要。Django REST Framework(DRF)提供了多种版本控制策略,包括 URLPathVersioningQueryParameterVersioningNamespaceVersioning,帮助我们灵活应对API的演化。

1. URLPathVersioning

URLPathVersioning 是一种将版本号嵌入到URL路径中的版本控制方式。例如,/api/v1/resource//api/v2/resource/ 分别对应API的第一个版本和第二个版本。

我们可以在 settings.py 中配置默认的版本控制类为 URLPathVersioning

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
    'DEFAULT_VERSION': 'v1',
    'ALLOWED_VERSIONS': ['v1', 'v2'],
}

然后,在 urls.py 中配置路径版本号。

from django.urls import path
from .views import ResourceAPIView
urlpatterns = [
    path('api/v1/resource/', ResourceAPIView.as_view(), name='resource_v1'),
    path('api/v2/resource/', ResourceAPIView.as_view(), name='resource_v2'),
]

通过这种方式,客户端可以通过指定不同的URL路径来访问不同版本的API。

2. QueryParameterVersioning

QueryParameterVersioning 是另一种常见的版本控制策略,它通过在请求URL中添加查询参数来指定API版本。例如,/api/resource/?version=1/api/resource/?version=2 分别对应API的第一个版本和第二个版本。

settings.py 中配置 QueryParameterVersioning

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning',
    'DEFAULT_VERSION': 'v1',
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    'VERSION_PARAM': 'version',
}

通过这种方式,客户端可以通过在请求URL中指定查询参数来选择所需的API版本。

3. NamespaceVersioning

NamespaceVersioning 是一种通过URL命名空间来实现API版本控制的策略。它允许我们为不同版本的API分配不同的URL命名空间,从而实现版本隔离。

urls.py 中配置命名空间。

from django.urls import path, include
urlpatterns = [
    path('api/v1/', include(('myapp.urls_v1', 'myapp'), namespace='v1')),
    path('api/v2/', include(('myapp.urls_v2', 'myapp'), namespace='v2')),
]

在视图中,我们可以通过 reverse 函数或 reverse_lazy 函数生成对应版本的URL。

from django.urls import reverse
class SomeAPIView(APIView):
    def get(self, request):
        url_v1 = reverse('v1:resource-detail', kwargs={'pk': 1})
        url_v2 = reverse('v2:resource-detail', kwargs={'pk': 1})
        return Response({'v1_url': url_v1, 'v2_url': url_v2})

这种版本控制方式特别适用于大型项目,通过URL命名空间可以有效管理不同版本的API,并确保版本之间的隔离。

📌 REST Framework 版本控制 - AcceptHeaderVersioning:通过请求头实现版本选择

AcceptHeaderVersioning 是一种通过HTTP请求头中的 Accept 字段来控制API版本的策略。客户端通过在请求头中指定版本信息,来请求不同版本的API。

settings.py 中配置 AcceptHeaderVersioning

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning',
    'DEFAULT_VERSION': 'v1',
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    'VERSION_PARAM': 'version',
}

然后,客户端可以通过如下方式指定版本信息:

curl -H "Accept: application/vnd.example.v1+json" https://example.com/api/resource/

curl -H "Accept: application/vnd.example.v2+json" https://example.com/api/resource/

通过这种方式,API的版本信息直接嵌入到请求头中,提升了请求URL的可读性,并且有助于保持URL的简洁。


目录
相关文章
|
7月前
|
消息中间件 监控 前端开发
如何开发项目管理系统中的项目结项板块?(附架构图+流程图+代码参考)
在企业项目管理中,“项目结项”是关键环节,常因流程不清、文档不全、审批滞后等问题导致交付困难。本文介绍如何通过“项目结项”模块实现线上化管理,涵盖结项申请、审批流程、成果上传、权限控制等功能,帮助团队高效完成项目收尾,避免成果丢失与流程混乱。内容包括功能设计、业务流程、系统架构、数据库设计、核心代码实现、前端交互及优化建议,助力项目管理系统快速落地并稳定运行。
|
6月前
|
人工智能 自然语言处理 JavaScript
Github又一AI黑科技项目,打造全栈架构,只需一个统一框架?
Motia 是一款现代化后端框架,融合 API 接口、后台任务、事件系统与 AI Agent,支持 JavaScript、TypeScript、Python 多语言协同开发。它提供可视化 Workbench、自动观测追踪、零配置部署等功能,帮助开发者高效构建事件驱动的工作流,显著降低部署与运维成本,提升 AI 项目落地效率。
613 0
|
7月前
|
数据挖掘 项目管理 Python
如何开发项目管理系统中的项目启动板块?(附架构图+流程图+代码参考)
本文介绍了项目管理系统中“项目启动”板块的设计与实现,涵盖功能模块、业务流程、开发技巧及效果展示,并提供代码参考和常见问题解答,助力企业高效搭建项目管理平台。
|
9月前
|
存储 消息中间件 前端开发
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
校园圈子系统校园论坛小程序采用uni-app前端框架,支持多端运行,结合PHP后端(如ThinkPHP/Laravel),实现用户认证、社交关系管理、动态发布与实时聊天功能。前端通过组件化开发和uni.request与后端交互,后端提供RESTful API处理业务逻辑并存储数据于MySQL。同时引入Redis缓存热点数据,RabbitMQ处理异步任务,优化系统性能。核心功能包括JWT身份验证、好友系统、WebSocket实时聊天及活动管理,确保高效稳定的用户体验。
532 4
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
|
7月前
|
缓存 Java 数据库
Java 项目分层架构实操指南及长尾关键词优化方案
本指南详解基于Spring Boot与Spring Cloud的Java微服务分层架构,以用户管理系统为例,涵盖技术选型、核心代码实现、服务治理及部署实践,助力掌握现代化Java企业级开发方案。
358 2
|
7月前
|
存储 Java 数据库连接
简单学Spring Boot | 博客项目的三层架构重构
本案例通过采用三层架构(数据访问层、业务逻辑层、表现层)重构项目,解决了集中式开发导致的代码臃肿问题。各层职责清晰,结合依赖注入实现解耦,提升了系统的可维护性、可测试性和可扩展性,为后续接入真实数据库奠定基础。
593 0
|
7月前
|
监控 前端开发 BI
如何开发项目管理系统中的项目收支板块?(附架构图+流程图+代码参考)
本文深入讲解项目管理系统中项目收支模块的设计与实现,涵盖预算、收入与支出管理,以及报表分析功能。内容包括模块功能概述、业务流程、开发技巧与实现方法,并提供数据库设计及前后端代码示例,助力企业打造高效的项目财务管控系统。
|
7月前
|
SQL 前端开发 项目管理
如何开发项目管理系统中的项目执行板块?(附架构图+流程图+代码参考)
随着企业项目规模扩大,传统管理方式已难以满足需求。本文介绍项目管理系统中“项目执行”板块的开发,涵盖任务管理、创建、验收及进度汇报等核心环节。通过功能设计、业务流程和开发技巧,结合代码示例,帮助企业高效推进项目执行,提升管理效率。
|
8月前
|
设计模式 开发者
一、HarmonyOS Next 开发者手册项目之项目架构设计
该项目是一个基于HarmonyOS Next的开发者学习手册应用,旨在帮助开发者系统学习HarmonyOS开发知识。项目采用分级学习方式,从基础到高级逐步深入讲解技术与实践案例。前四章重点介绍应用架构相关内容,助力快速掌握应用核心。 项目结构清晰,包含主入口、源代码目录、公共资源和工具等。页面导航分为多个阶段:萌新小白(基础入门)、登堂入室(进阶学习)、进阶高手(高级开发)。支持Markdown解析,使用`@luvi/lv-markdown-in`插件展示内容,并定义了多种数据结构以规范开发流程。 源码已开源,持续更新中
232 1
|
11月前
|
存储 数据采集 机器学习/深度学习
新闻聚合项目:多源异构数据的采集与存储架构
本文探讨了新闻聚合项目中数据采集的技术挑战与解决方案,指出单纯依赖抓取技术存在局限性。通过代理IP、Cookie和User-Agent的精细设置,可有效提高采集策略;但多源异构数据的清洗与存储同样关键,需结合智能化算法处理语义差异。正反方围绕技术手段的有效性和局限性展开讨论,最终强调综合运用代理技术与智能数据处理的重要性。未来,随着机器学习和自然语言处理的发展,新闻聚合将实现更高效的热点捕捉与信息传播。附带的代码示例展示了如何从多个中文新闻网站抓取数据并统计热点关键词。
541 2
新闻聚合项目:多源异构数据的采集与存储架构

热门文章

最新文章