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

Django登录认证后部分视图返回AnonymousUser问题排查

Django登录后部分视图无法获取认证用户问题排查

问题现象

调用login()完成用户登录后,CheckAuthView视图能通过request.user.is_authenticated正常识别已认证用户,但CreateClubView视图中request.user返回AnonymousUser,访问request.session['id']触发KeyError。登录接口返回成功,且前端可通过CheckAuthView验证登录状态并访问首页。

相关代码

登录视图LoginView

class LoginView(APIView):
    serializer_class = LoginUserSerializer

    def post(self, request):         
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            username = serializer.data.get('username')
            password = serializer.data.get('password')

            # 检查用户是否存在
            user_exist_query = User.objects.filter(username=username)
            if not user_exist_query.exists():
                return JsonResponse({"error": "用户名不存在"}, status = 401)

            # 验证用户名密码
            user_auth_query = authenticate(username=username, password=password)
            if user_auth_query is not None:
                login(request, user_auth_query)
                return JsonResponse({"message": "登录成功"}, status = 200)
            else:
                return JsonResponse({"error": "用户名或密码错误"}, status = 401)
        return JsonResponse({"error": "请求参数错误"}, status=400)

正常工作的CheckAuthView视图

class CheckAuthView(APIView):
    def get(self, request):
        if request.user.is_authenticated:
            return Response(status=status.HTTP_200_OK)
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)

该视图用于保护React前端路由,已登录时允许访问首页,未登录则跳转,证明此处request.user可获取真实用户。

存在问题的CreateClubView视图

class CreateClubView(APIView):
    serilizer_class = ClubSerializer
    
    def post(self, request):
        serializer = self.serilizer_class(data=request.data)

        print(request.user.is_authenticated)
        
        if serializer.is_valid():
            clubName = serializer.data.get('name')
            clubDesc = serializer.data.get('description')
            clubLoc = serializer.data.get('location')
            clubEmail = serializer.data.get('email')
            clubContact = serializer.data.get('contact')
            clubWebsite = serializer.data.get('website')
            clubOrganizer = request.session['id']
            
            queryset = Club.objects.filter(name=clubName)
            if queryset.exists():
                return Response(status=status.HTTP_400_BAD_REQUEST)
            
            club = Club.objects.create(name=clubName, description=clubDesc, location=clubLoc, 
                                    email=clubEmail, contact=clubContact, website=clubWebsite, organizer=clubOrganizer)
            club.save()
            
            return Response(status=status.HTTP_201_CREATED)
        
        return Response(status=status.HTTP_400_BAD_REQUEST)

打印request.user返回AnonymousUser,访问request.session['id']触发KeyError。

前端React调用代码

const response: Response = await fetch('http://127.0.0.1:8000/api/clubs/create', {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(form),
})

if (response.ok) {
    console.log("俱乐部创建成功");
    navigate("/home");
} else {
    console.log("俱乐部创建失败");
}

Django中间件配置

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    'corsheaders.middleware.CorsMiddleware',
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

排查方向与解决方案

Django Session认证依赖sessionid Cookie传递用户会话信息,fetch API默认不会自动携带Cookie。需修改前端请求配置:

const response: Response = await fetch('http://127.0.0.1:8000/api/clubs/create', {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(form),
    credentials: 'include' // 强制携带Cookie
})

2. CORS配置未允许凭证传递

检查Django settings.py中的CORS配置,确保开启允许凭证:

CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",  # 替换为你的前端实际地址
]

3. 修正视图拼写错误(次要)

CreateClubView中的serilizer_class拼写错误,应为serializer_class,虽不影响认证,但建议修正以避免潜在问题。

4. 避免直接操作Session获取用户ID

无需手动存储request.session['id'],认证成功后直接使用request.user.id即可,同时建议先校验用户认证状态:

class CreateClubView(APIView):
    serializer_class = ClubSerializer
    
    def post(self, request):
        # 先校验用户是否认证
        if not request.user.is_authenticated:
            return Response(status=status.HTTP_401_UNAUTHORIZED)
            
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            # 替换原session取值逻辑
            clubOrganizer = request.user.id
            # 其余代码保持不变

总结

核心问题是前端请求未携带Session Cookie,导致后端无法识别用户会话。优先修正前端fetch的credentials配置,同时确保Django的CORS设置允许凭证传递,即可解决request.user为匿名用户的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 06:22:52