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

如何在普通Django视图而非DRF视图中使用djangorestframework-jwt

在普通Django视图中实现JWT身份验证的方案

先直接回答你的核心疑问:djangorestframework-jwt的中间件无法直接用于普通Django视图——它是专门为DRF的视图体系设计的,依赖DRF封装的Request对象和专属认证流程,普通Django视图的HttpRequest对象不会触发它的认证逻辑。

不过你完全可以自己实现类似@login_required的JWT认证装饰器,或者用轻量方式适配DRF的认证能力,下面给你两种可行方案:

方案一:自定义JWT认证装饰器(推荐)

这是最直接可控的方式,手动处理令牌的提取、验证和用户绑定,使用方式和@login_required完全一致。

步骤1:编写自定义装饰器

import jwt
from django.http import JsonResponse
from django.conf import settings
from django.contrib.auth import get_user_model
from functools import wraps

User = get_user_model()

def jwt_required(view_func):
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        # 从请求头获取遵循Bearer规范的令牌
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return JsonResponse({'error': '请提供有效的JWT令牌'}, status=401)
        
        token = auth_header.split(' ')[1]
        try:
            # 解码令牌,验证签名、算法和有效期
            payload = jwt.decode(
                token, 
                settings.SECRET_KEY, 
                algorithms=['HS256'],
                options={"verify_exp": True}
            )
            # 根据payload中的用户ID获取对应用户
            user = User.objects.get(id=payload['id'])
            # 将用户绑定到request对象,和@login_required效果一致
            request.user = user
        except jwt.ExpiredSignatureError:
            return JsonResponse({'error': '令牌已过期'}, status=401)
        except jwt.InvalidTokenError:
            return JsonResponse({'error': '无效的JWT令牌'}, status=401)
        except User.DoesNotExist:
            return JsonResponse({'error': '关联用户不存在'}, status=401)
        
        return view_func(request, *args, **kwargs)
    return wrapper

步骤2:在普通视图中使用装饰器

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
@jwt_required
def protected_user_data(request):
    if request.method == 'GET':
        # 验证通过后,request.user就是当前认证的用户
        return JsonResponse({
            'id': request.user.id,
            'username': request.user.username,
            'email': request.user.email  # 假设你的用户模型包含email字段
        })

方案二:适配DRF的认证类(可选)

如果你不想自己写解码逻辑,可以在普通视图中手动调用DRF-JWT的认证类,不过需要先把普通HttpRequest转换成DRF的Request对象:

from rest_framework.request import Request
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def protected_view(request):
    # 将普通HttpRequest包装成DRF的Request对象
    drf_request = Request(request)
    try:
        # 使用DRF-JWT的认证类完成令牌验证
        user, token = JSONWebTokenAuthentication().authenticate(drf_request)
        request.user = user
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=401)
    
    # 验证通过后处理业务逻辑
    return JsonResponse({'message': '认证成功', 'username': request.user.username})

这个方案的好处是复用了DRF-JWT的成熟逻辑,但缺点是需要引入DRF的Request对象,对于纯普通Django视图来说有点冗余。

补充说明

  • 令牌传递:推荐使用Authorization: Bearer <token>的请求头方式,比放在URL参数或表单里更安全。
  • 自定义装饰器可扩展:比如添加令牌刷新逻辑、支持多种令牌来源、或结合Django的user_passes_test做权限校验。
  • DRF-JWT中间件的局限:它是DRF视图体系的一部分,只会在处理DRF的View类时生效,普通函数视图不会触发它的认证流程,直接加到Django中间件列表里没用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:14:17