React调用Django登录接口返回成功但用户仍为AnonymousUser的问题
Django登录接口返回200但用户仍为AnonymousUser的修复方案
问题复现
Django 后端代码
@method_decorator(csrf_exempt, name='dispatch') class UserLoginView(GenericAPIView): permission_classes = (AllowAny,) serializer_class = UserLoginSerializer def post(self, request): serializer = self.serializer_class(data=request.data) user = serializer.validate(request.data) if user is None: return Response(status=status.HTTP_400_BAD_REQUEST) else: user.before_last_login = user.last_login login(request, user) user.save() user = UserSerializer(user) return Response(data={'id': user.data['id'], 'img': user.data['image']} , status=status.HTTP_200_OK)
React 前端代码
const res = await axios.post(`${APIURL}/account/login/`, { id: id, password: pwd, });
调用接口后收到200成功响应,但后续请求中Django识别用户仍为AnonymousUser,实际登录状态未维持。
问题核心原因
- Session Cookie未被前端处理:Django的
login()函数会生成session并设置对应的Cookie,但axios默认不会自动接收和携带Cookie,导致后续请求无法传递session标识,服务器无法识别已登录用户。 - 跨域配置缺失(跨域场景):若前后端域名不同,Django未配置允许跨域携带Cookie,即使前端开启Cookie携带,也无法完成session的跨域传递。
修复步骤
1. 配置Axios允许携带Cookie
修改前端请求代码,开启withCredentials选项,让axios自动处理session Cookie:
const res = await axios.post(`${APIURL}/account/login/`, { id: id, password: pwd, }, { withCredentials: true // 关键:开启Cookie携带 });
如果需要全局生效,可在项目初始化时配置:
import axios from 'axios'; axios.defaults.withCredentials = true;
2. 配置Django跨域支持(跨域场景)
如果前后端为跨域部署,需要安装并配置django-cors-headers:
- 安装依赖:
pip install django-cors-headers
- 在
settings.py中添加配置:
INSTALLED_APPS = [ # ... 其他已安装应用 'corsheaders', ] MIDDLEWARE = [ # 注意顺序:需放在CommonMiddleware之前 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... 其他中间件 ] # 替换为你的前端实际域名 CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "https://your-frontend-domain.com", ] # 允许跨域携带Cookie CORS_ALLOW_CREDENTIALS = True
3. 验证登录逻辑有效性
确保UserLoginSerializer.validate()方法正确返回有效用户实例,可在login()后添加日志确认:
import logging logger = logging.getLogger(__name__) # 在login(request, user)后添加 logger.info(f"用户 {user.username} 已登录,session key: {request.session.session_key}")
4. 恢复CSRF保护(可选,提升安全性)
若已完成跨域CSRF配置,可移除csrf_exempt装饰器,改用CSRF令牌机制:
- 前端获取并携带CSRF令牌:
function getCsrfToken() { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, 10) === 'csrftoken=') { cookieValue = decodeURIComponent(cookie.substring(10)); break; } } } return cookieValue; } // 登录请求携带CSRF头 const res = await axios.post(`${APIURL}/account/login/`, { id: id, password: pwd, }, { withCredentials: true, headers: { 'X-CSRFToken': getCsrfToken() } });
- 后端移除
@method_decorator(csrf_exempt, name='dispatch'),启用默认CSRF保护。
验证修复效果
登录成功后,发起一个需要登录权限的请求,检查request.user是否为已登录用户,而非AnonymousUser。
内容的提问来源于stack exchange,提问作者sen
相关产品推荐
相关产品推荐

