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

Django跨App用Mixin获取登录用户返回AnonymousUser问题求助

DRF登录后request.user返回AnonymousUser问题修复

问题表现

基于Django REST Framework + React前后端分离架构开发时,调用原生登录接口完成登录后,自定义权限Mixin中读取request.user始终返回匿名用户,无法获取已登录用户信息。

核心根因

  • 自定义storekeeperMixin的dispatch方法未调用父类实现、未返回响应,DRF完整请求处理链路被截断,内置认证逻辑根本没有执行,用户信息不会被加载到request对象中。
  • DRF默认未开启SessionAuthentication认证类,无法识别Django原生login()方法写入的session登录态。
  • 前端跨域请求未配置携带凭证,登录下发的sessionid、csrftoken cookie不会被浏览器保存,后续请求不会携带认证信息传给后端。
  • 跨域配置错误、CSRF cookie未正常下发,导致认证请求被拦截。

修复步骤

1. 修复自定义Mixin逻辑

补全dispatch方法的父类调用和响应返回,确保请求走完完整认证流程:

class storekeeperMixin():
    def dispatch(self, request, *args, **kwargs):
        # 调用父类dispatch,执行DRF内置的认证、权限、请求处理逻辑
        response = super().dispatch(request, *args, **kwargs)
        # 流程走完后再读取用户信息,此时已完成认证加载
        print('****************************' + str(request.user.username))
        # 必须返回响应,否则接口无法正常返回数据
        return response

class driverapi(storekeeperMixin,viewsets.ViewSet):
    def get(self,request,format=None):
        # 注意原代码笔误:object -> objects,Django模型默认管理器为objects
        driverslist = driver.objects.all()
        # 注意序列化器类名、变量名拼写和实际定义对齐
        serializer = OBJdriver(driverslist, many=True)
        return Response(serializer.data)

2. 配置DRF默认认证类

在项目settings.py中添加DRF配置,开启session认证对齐Django原生登录逻辑:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
    ],
    # 接口默认需要登录才能访问,可按需调整
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}

3. 补全登录接口装饰器

给登录接口添加请求方法限制、CSRF cookie下发装饰器,确保登录态cookie正常返回给前端:

import json

from django.contrib.auth import authenticate, login, logout
from django.http import JsonResponse
from django.middleware.csrf import get_token
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_POST

@require_POST
@ensure_csrf_cookie
def login_view(request):
    data = json.loads(request.body)
    username = data.get('username')
    password = data.get('password')

    if username is None or password is None:
        return JsonResponse({'detail': '请提供用户名和密码'}, status=400)

    user = authenticate(username=username, password=password)

    if user is None:
        return JsonResponse({'detail': '用户名或密码错误'}, status=400)

    login(request, user)
    return JsonResponse({'detail': '登录成功'})

# 前端初始化时可调用该接口获取CSRF cookie
@ensure_csrf_cookie
def get_csrf_token(request):
    return JsonResponse({'csrfToken': get_token(request)})

4. 前端请求配置

所有发往后端的请求必须开启携带凭证配置,确保cookie能跨域正常传输:

  • 若使用axios,添加全局配置:
import axios from 'axios'
// 跨域请求携带cookie
axios.defaults.withCredentials = true
// 自动从cookie读取CSRF token放到请求头,避免403报错
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'
  • 若使用原生fetch,每个请求添加credentials配置:
fetch('/api/your-endpoint/', {
  credentials: 'include',
  // 其余请求配置:method、headers、body等
})

5. 跨域配置检查

前后端端口不一致时,正确配置django-cors-headers:

  1. 安装依赖后在INSTALLED_APPS中添加corsheaders
  2. 在MIDDLEWARE最顶部添加corsheaders.middleware.CorsMiddleware
  3. 在settings.py中添加配置:
# 替换为前端实际部署地址,生产环境不要开启全源允许
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
]
# 允许跨域携带凭证
CORS_ALLOW_CREDENTIALS = True

注意:禁止同时开启CORS_ALLOW_ALL_ORIGINS = True和CORS_ALLOW_CREDENTIALS = True,浏览器会直接拦截该类响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:24:24