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

如何让DRF默认登录视图支持JSON格式请求?

解决DRF默认登录视图支持JSON请求的问题

默认的rest_framework.urls登录视图是为浏览器表单登录设计的,只会处理form-data格式请求,遇到JSON请求会返回HTML页面。以下是两种解决方法:

方法一:自定义JSON登录接口

直接编写专门处理JSON请求的登录视图,灵活可控:

  1. 在项目的views.py中添加自定义视图:
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from django.contrib.auth import authenticate, login

class JSONLoginView(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = authenticate(request, username=username, password=password)
        
        if user:
            login(request, user)
            return Response({
                'detail': '登录成功',
                'user_id': user.id,
                'username': user.username
            }, status=status.HTTP_200_OK)
        return Response({'detail': '用户名或密码错误'}, status=status.HTTP_400_BAD_REQUEST)
  1. 修改urls.py,新增JSON登录路径:
from django.urls import path, include
from .views import JSONLoginView

urlpatterns = [
    # 保留默认表单登录(供浏览器访问用,可选)
    path('drf-auth/', include('rest_framework.urls')),
    # 新增JSON专属登录接口
    path('api/login/', JSONLoginView.as_view(), name='api_login'),
]

方法二:修改默认登录视图的行为

如果想复用原有drf-auth/login路径,可重写默认视图:

  1. 在views.py中继承DRF的LoginView并修改逻辑:
from rest_framework.views import LoginView as DRFLoginView
from rest_framework.response import Response
from django.contrib.auth import authenticate, login

class LoginView(DRFLoginView):
    def post(self, request, *args, **kwargs):
        # 判断请求是否为JSON格式
        if request.content_type == 'application/json':
            username = request.data.get('username')
            password = request.data.get('password')
            user = authenticate(request, username=username, password=password)
            
            if user:
                login(request, user)
                return Response({'detail': '登录成功'}, status=200)
            return Response({'detail': '认证失败'}, status=400)
        # 非JSON请求走默认表单登录逻辑
        return super().post(request, *args, **kwargs)
  1. 在urls.py中覆盖默认的登录路由:
from django.urls import path, include
from .views import LoginView

urlpatterns = [
    # 覆盖默认登录视图
    path('drf-auth/login/', LoginView.as_view(), name='rest_login'),
    path('drf-auth/', include('rest_framework.urls')),
]

关键注意事项

  • 发送JSON请求时,必须确保请求头的Content-Type设置为application/json(Postman选Raw-JSON格式会自动设置;Axios发送JSON数据时默认自动配置)。
  • 会话认证需要处理CSRF令牌:Axios需开启withCredentials: true,前端要从Cookie中获取csrftoken并在请求头中携带X-CSRFToken。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:16:02