如何让DRF默认登录视图支持JSON格式请求?
解决DRF默认登录视图支持JSON请求的问题
默认的rest_framework.urls登录视图是为浏览器表单登录设计的,只会处理form-data格式请求,遇到JSON请求会返回HTML页面。以下是两种解决方法:
方法一:自定义JSON登录接口
直接编写专门处理JSON请求的登录视图,灵活可控:
- 在项目的
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)
- 修改
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路径,可重写默认视图:
- 在
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)
- 在
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
相关产品推荐
相关产品推荐

