You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用rest_framework_simplejwt实现无需用户身份的API JWT令牌认证?

解决方案:自定义无用户关联的JWT认证类

默认的Django REST JWT认证(如djangorestframework-simplejwt)会强制从令牌中提取用户标识(如user_id)并关联到系统用户,这就是你遇到"Token contained no recognizable user identification"错误的核心原因。针对仅验证令牌有效性、无需关联特定用户的场景,标准方案是自定义JWT认证逻辑,跳过用户查询步骤。

步骤1:自定义JWT认证类

创建一个继承自现有JWT认证类的自定义认证器,重写凭证验证方法,只校验令牌的签名和有效期,不查询用户:

# your_app/authentication.py
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.tokens import Token
from rest_framework import exceptions
from django.contrib.auth.models import AnonymousUser

class NoUserJWTAuthentication(JWTAuthentication):
    def authenticate_credentials(self, token: Token) -> tuple[AnonymousUser, Token]:
        # 仅验证令牌签名和有效期,跳过用户查询
        try:
            token.verify()
        except Exception:
            raise exceptions.AuthenticationFailed("Token is invalid or expired")
        
        # 返回匿名用户对象(满足DRF认证接口的返回要求)和令牌
        return (AnonymousUser(), token)

步骤2:配置认证类

可以全局配置该认证类,或在需要的特定视图中单独指定:

全局配置(settings.py)

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'your_app.authentication.NoUserJWTAuthentication',
        # 保留项目中其他需要的认证类
    ],
}

视图单独配置

# your_app/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from your_app.authentication import NoUserJWTAuthentication

class PublicAPIView(APIView):
    authentication_classes = [NoUserJWTAuthentication]
    
    def get(self, request):
        # 认证通过后即可处理请求,request.user为AnonymousUser实例
        return Response({"status": "success", "message": "Token validated successfully"})

步骤3:生成无用户关联的JWT令牌

默认JWT生成逻辑会绑定用户,需要自定义令牌生成函数,生成不包含用户标识的令牌:

# your_app/utils.py
from rest_framework_simplejwt.tokens import UntypedToken
from rest_framework_simplejwt.settings import api_settings
import jwt

def generate_anonymous_jwt():
    # 创建无用户令牌,设置有效期(此处使用项目配置的15分钟)
    token = UntypedToken()
    token.set_exp(lifetime=api_settings.ACCESS_TOKEN_LIFETIME)
    
    # 编码令牌,仅包含过期时间和签名信息
    encoded_token = jwt.encode(
        token.payload,
        api_settings.SECRET_KEY,
        algorithm=api_settings.ALGORITHM
    )
    return encoded_token

替代方案:API Key认证

如果项目允许调整认证方案,DRF内置的TokenAuthentication或第三方库(如django-rest-framework-api-key)的API Key认证更适合无用户关联的场景,实现更轻量化。但如果项目强制要求使用JWT,自定义认证类是最优的标准实现方式。

内容的提问来源于stack exchange,提问作者VADeR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 10:59:55