DRF中PUT请求识别为AnonymousUser,GET请求认证正常问题求助
这个问题我之前在开发DRF项目时也碰到过,从你的日志和代码来看,核心原因就是PUT请求没有正确携带认证凭据,导致DRF无法识别你的登录用户身份,下面分几个方向排查解决:
1. 先查前端PUT请求的认证头是否正确
你用fetch发起PUT请求时,一定要确保请求头里包含后端认证所需的信息——比如如果你的DRF用的是TokenAuthentication,请求头里必须有Authorization: Token <你的登录令牌>。
你可以先打开浏览器的开发者工具→网络标签,找到这个PUT请求,查看它的Request Headers:
- 确认
Authorization(或你项目用的其他认证头字段)是否存在,且令牌值正确。
如果头信息缺失,要检查api.httpHeaders的配置,比如:
// 示例:如果是Token认证的配置方式 const api = { authurl: '/api/', httpHeaders: { 'Content-Type': 'application/json', // 从本地存储里取出登录时拿到的token 'Authorization': `Token ${localStorage.getItem('userToken')}` } }
2. 检查后端认证与CSRF配置
如果你的项目用了SessionAuthentication(比如和Django自带的登录系统结合),那么PUT/POST这类修改型请求必须携带CSRF token,而GET请求不需要——这就是为什么GET能正常识别用户,PUT不行的原因。
后端配置确认
先看settings.py里的DRF配置:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', # 按需启用 ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', # 确保只有登录用户能访问 ] }
前端添加CSRF token
如果用了Session认证,前端要从cookie里获取CSRF token并加入请求头:
// 从浏览器cookie中获取Django生成的CSRF token function getCsrfToken() { let token = null; if (document.cookie) { const cookies = document.cookie.split(';'); for (let cookie of cookies) { const [key, value] = cookie.trim().split('='); if (key === 'csrftoken') { token = decodeURIComponent(value); break; } } } return token; } // 发起PUT请求时加入CSRF头 const csrftoken = getCsrfToken(); const response = await fetch(`${api.authurl}/order_items/${order_item.id}/`, { method: 'PUT', headers: { ...api.httpHeaders, 'X-CSRFToken': csrftoken }, body: JSON.stringify(order_item) });
3. 确认视图集的权限配置
虽然你的OrderItemViewSet继承了ModelViewSet,默认会继承全局权限配置,但还是可以检查下有没有给这个视图集单独设置错误的权限:
from rest_framework import permissions class OrderItemViewSet(viewsets.ModelViewSet): serializer_class = OrderItemSerializer # 明确指定只有登录用户能访问 permission_classes = [permissions.IsAuthenticated] def get_queryset(self): print('Current User', self.request.user, self.action) return OrderItem.objects.filter(order__owner=self.request.user.profile)
4. 排查请求URL是否正确
虽然从日志看PUT请求返回了200,但还是要确认api.authurl是否和GET请求的URL完全一致——比如有没有误写了域名、路径前缀,导致访问了未配置认证的路由。
总结
最常见的情况就是PUT请求没带对认证凭据(token或CSRF token),优先排查前端请求头,再对应检查后端的认证配置,应该就能解决问题。
内容的提问来源于stack exchange,提问作者Storm Llamas

