如何在Django Rest Framework中用simple-jwt结合JWK Url实现跨微服务远程用户认证?
可行性与实现方案
完全可行,通过djangorestframework-simplejwt的JWK端点配合自定义认证后端,就能实现跨服务的JWT验证+自动创建本地用户的需求,具体实现步骤如下:
一、Todo Auth服务(认证中心)配置
1. 依赖与基础配置
安装依赖:
pip install djangorestframework-simplejwt
在settings.py中配置JWT使用非对称加密(RS256),并指定密钥路径:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], } SIMPLE_JWT = { 'ALGORITHM': 'RS256', 'PRIVATE_KEY': open('private_key.pem').read(), 'PUBLIC_KEY': open('public_key.pem').read(), 'AUTH_HEADER_TYPES': ('Bearer',), }
2. 生成RSA密钥对
执行以下命令生成RSA密钥对(用于非对称加密):
openssl genrsa -out private_key.pem 2048 openssl rsa -in private_key.pem -pubout -out public_key.pem
3. 暴露JWK端点
在urls.py中添加JWK接口,供Todo Project获取公钥:
from rest_framework_simplejwt.views import JWKSView urlpatterns = [ # 其他路由... path('jwks/', JWKSView.as_view(), name='jwks'), ]
启动Todo Auth服务(比如端口8000),此时http://localhost:8000/jwks/会返回标准JWK格式的公钥信息。
二、Todo Project服务(业务服务)配置
1. 依赖安装
同样安装依赖:
pip install djangorestframework-simplejwt
2. 自定义认证后端
创建authentication.py,实现远程JWT验证+自动创建用户逻辑:
from rest_framework_simplejwt.authentication import JWTAuthentication from rest_framework_simplejwt.exceptions import InvalidToken, AuthenticationFailed from rest_framework_simplejwt.jwks import JWKClient from django.contrib.auth.models import User class RemoteJWTAuthBackend(JWTAuthentication): def __init__(self): super().__init__() self.jwk_client = JWKClient('http://localhost:8000/jwks/') def authenticate(self, request): # 获取请求头中的Token header = self.get_header(request) if header is None: return None raw_token = self.get_raw_token(header) if raw_token is None: return None # 从JWK端点获取公钥并验证Token try: signing_key = self.jwk_client.get_signing_key_from_jwt(raw_token) validated_token = self.get_validated_token(raw_token) except (InvalidToken, AuthenticationFailed): return None # 解析用户信息,自动创建本地用户 user_data = validated_token.payload username = user_data.get('username') email = user_data.get('email', '') user, created = User.objects.get_or_create( username=username, defaults={'email': email} ) return (user, validated_token)
3. 配置认证后端
在settings.py中替换默认认证类为自定义后端:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'your_app.authentication.RemoteJWTAuthBackend', ], } SIMPLE_JWT = { 'ALGORITHM': 'RS256', # 不指定本地公钥,通过JWK端点动态获取 'VERIFYING_KEY': None, 'AUTH_HEADER_TYPES': ('Bearer',), }
4. 跨域处理(开发环境)
由于两个服务在不同端口,需解决跨域问题,安装并配置django-cors-headers:
pip install django-cors-headers
在settings.py中添加配置:
INSTALLED_APPS = [ # 其他应用... 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # 其他中间件... ] CORS_ALLOW_ALL_ORIGINS = True # 开发环境临时使用,生产环境需指定具体域名
三、关键注意事项
- 必须使用非对称加密算法(如RS256):JWK的核心作用是安全分发公钥,对称加密(HS256)不需要JWK,不符合需求。
- 生产环境需改用HTTPS:避免JWK和Token在传输过程中被篡改。
- 自定义用户模型:如果项目使用自定义User模型,需修改认证后端中的用户创建逻辑,替换默认的
User为自定义模型。
内容的提问来源于stack exchange,提问作者John Anderson
相关产品推荐
相关产品推荐

