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

如何用DRF构建API,实现JWT校验及带参数的多数据端点服务

Django API开发:JWT检查、参数获取与端点设计指南

Hey there! Let's break down your questions step by step since you're new to building APIs in Django—no worries, we'll get this sorted out clearly.

1. 如何提取JWT令牌?

JWT令牌通常是通过请求头的Authorization字段传递的,格式一般是Bearer <your-token-here>。在Django中,你可以直接从request.META中获取这个字段,不需要额外的端点来接收它(除非你的客户端是通过POST body发送,但这不符合标准API设计规范)。

举个简单的提取和存在性检查逻辑:

def check_jwt_exists(request):
    auth_header = request.META.get('HTTP_AUTHORIZATION')
    # 只检查令牌是否存在且格式正确,不验证签名(符合你的需求)
    return auth_header and auth_header.startswith('Bearer ')

你可以在需要的视图里调用这个函数,判断是否允许POST操作。

2. ID参数的获取方式

ID参数的获取分两种常见场景:

  • URL路径参数:比如你的端点是../api/contact/<int:contact_id>/,那么在视图函数里可以直接把ID作为参数接收:
    @api_view(['GET', 'POST'])
    def contact_detail(request, contact_id):
        # contact_id就是URL里的ID值,直接用它查询数据即可
        pass
    
    对应的urls.py配置:
    path('api/contact/<int:contact_id>/', views.contact_detail, name='contact-detail')
    
  • 查询参数:如果ID是通过URL的查询字符串传递(比如../api/contact/?id=123),可以用request.GET获取:
    contact_id = request.GET.get('id')
    # 记得处理参数不存在的情况,比如返回400错误
    

3. 是否需要单独的POST端点?

完全不需要!你可以在同一个端点里处理GET和POST请求,用@api_view(['GET', 'POST'])装饰器,然后根据request.method分支处理逻辑。这样更符合RESTful设计规范,也让你的API结构更简洁。

4. 序列化与数据保存完整示例

结合上面的JWT检查和参数获取,给你一个完整的视图示例,以contact端点为例:

首先创建序列化器(serializers.py):

from rest_framework import serializers
from .models import Contact

class ContactSerializer(serializers.ModelSerializer):
    class Meta:
        model = Contact
        fields = '__all__'  # 或者指定你需要的字段,比如['id', 'name', 'email']

然后在views.py中编写视图:

from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework import status
from .models import Contact
from .serializers import ContactSerializer

def check_jwt_exists(request):
    auth_header = request.META.get('HTTP_AUTHORIZATION')
    return auth_header and auth_header.startswith('Bearer ')

@api_view(['GET', 'POST'])
def contact_list(request):
    # 处理GET请求:返回所有联系人数据
    if request.method == 'GET':
        contacts = Contact.objects.all()
        serializer = ContactSerializer(contacts, many=True)
        return Response(serializer.data)
    
    # 处理POST请求:检查JWT后保存数据
    elif request.method == 'POST':
        if not check_jwt_exists(request):
            return Response({"error": "JWT token is required for POST requests"}, status=status.HTTP_403_FORBIDDEN)
        
        serializer = ContactSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# 带ID参数的详情视图(支持查询、编辑、删除)
@api_view(['GET', 'PUT', 'DELETE'])
def contact_detail(request, contact_id):
    try:
        contact = Contact.objects.get(pk=contact_id)
    except Contact.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)
    
    if request.method == 'GET':
        serializer = ContactSerializer(contact)
        return Response(serializer.data)
    
    # 编辑或删除操作也可以添加JWT检查,按需调整
    elif request.method == 'PUT':
        if not check_jwt_exists(request):
            return Response({"error": "JWT token is required"}, status=status.HTTP_403_FORBIDDEN)
        serializer = ContactSerializer(contact, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

然后在urls.py中配置多个端点:

from django.urls import path
from . import views

urlpatterns = [
    path('api/contact/', views.contact_list, name='contact-list'),
    path('api/contact/<int:contact_id>/', views.contact_detail, name='contact-detail'),
    path('api/qualifications/', views.qualification_list, name='qualification-list'),
    # 按照同样的逻辑添加其他端点的配置即可
]

小提示:简化重复的JWT检查逻辑

如果多个视图都需要检查JWT,你可以把这个逻辑做成一个自定义装饰器,避免重复代码:

from functools import wraps
from rest_framework.response import Response
from rest_framework import status

def require_jwt(view_func):
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        auth_header = request.META.get('HTTP_AUTHORIZATION')
        if not auth_header or not auth_header.startswith('Bearer '):
            return Response({"error": "JWT token is required"}, status=status.HTTP_403_FORBIDDEN)
        return view_func(request, *args, **kwargs)
    return wrapper

然后在需要的视图上直接使用:

@api_view(['POST'])
@require_jwt
def create_contact(request):
    # 处理POST逻辑即可,无需再写JWT检查代码
    pass

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:27:15