如何在Django REST Framework中实现跨微服务的JWT令牌验证?
实现方案
一、todo_auth 服务配置(令牌验证服务)
1. 新增令牌验证接口
在 todo_auth/views.py 中添加视图,对外暴露令牌验证能力:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from rest_framework_simplejwt.tokens import AccessToken from rest_framework_simplejwt.exceptions import InvalidToken, TokenError class TokenValidateView(APIView): permission_classes = [] # 无需权限即可访问验证接口 def post(self, request): token = request.data.get('token') if not token: return Response({'error': 'Token缺失'}, status=status.HTTP_400_BAD_REQUEST) try: access_token = AccessToken(token) # 验证通过后返回用户核心信息 return Response({ 'valid': True, 'user_id': access_token['user_id'] }, status=status.HTTP_200_OK) except (InvalidToken, TokenError) as e: return Response({'valid': False, 'error': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
2. 配置接口路由
在 todo_auth/urls.py 中添加验证接口的路由:
from django.urls import path from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView from .views import TokenValidateView urlpatterns = [ # 保留原有JWT令牌生成、刷新路由 path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), # 新增令牌验证路由 path('api/token/validate/', TokenValidateView.as_view(), name='token_validate'), ]
3. 跨域配置(必要时)
由于两个服务在同服务器不同端口,属于跨域场景,需配置CORS允许todo服务访问:
- 安装依赖:
pip install django-cors-headers
- 在
todo_auth/settings.py中配置:
INSTALLED_APPS = [ ... 'corsheaders', ... ] MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... ] # 允许todo服务的端口(示例为8001) CORS_ALLOWED_ORIGINS = [ "http://localhost:8001", ]
二、todo 服务配置(待办业务服务)
1. 编写令牌验证工具函数
在 todo/utils.py 中实现请求todo_auth验证接口的逻辑:
import requests from rest_framework import status def validate_token(token): # 替换为todo_auth服务的实际地址 auth_validate_url = "http://localhost:8000/api/token/validate/" try: response = requests.post(auth_validate_url, json={'token': token}) return response.json() except requests.exceptions.RequestException: return {'valid': False, 'error': '认证服务不可用'}
2. 自定义权限验证类
在 todo/permissions.py 中创建权限类,统一处理令牌验证:
from rest_framework.permissions import BasePermission from rest_framework.exceptions import PermissionDenied from .utils import validate_token class TokenAuthPermission(BasePermission): def has_permission(self, request, view): # 从请求头提取Bearer令牌 auth_header = request.headers.get('Authorization') if not auth_header or not auth_header.startswith('Bearer '): raise PermissionDenied('请提供有效的身份令牌') token = auth_header.split(' ')[1] validation_result = validate_token(token) if not validation_result.get('valid'): raise PermissionDenied(validation_result.get('error', '令牌无效')) # 将验证后的用户ID存入request,供后续业务使用 request.user_id = validation_result.get('user_id') return True
3. 业务视图集成权限验证
在待办任务视图中使用自定义权限类,确保只有验证通过的用户才能访问:
from rest_framework.views import APIView from rest_framework.response import Response from .models import Todo from .permissions import TokenAuthPermission class UserTodoListView(APIView): permission_classes = [TokenAuthPermission] def get(self, request): # 根据验证后的user_id查询用户专属待办 user_todos = Todo.objects.filter(user_id=request.user_id).values() return Response({'todos': list(user_todos)})
核心流程说明
- 前端从todo_auth服务获取JWT令牌(通过
/api/token/接口) - 前端请求todo服务时,将令牌放在
Authorization: Bearer <token>请求头中 - todo服务通过自定义权限类,将令牌转发至todo_auth的验证接口
- 验证通过后,todo服务根据返回的user_id查询用户专属待办并返回结果
内容的提问来源于stack exchange,提问作者John Anderson
相关产品推荐
相关产品推荐

