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

DRF中PUT请求识别为AnonymousUser,GET请求认证正常问题求助

解决DRF中PUT请求识别为匿名用户的问题

这个问题我之前在开发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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:17:50