React前端调用Django DRF profile API时无法识别登录状态如何解决
问题描述
基于Django REST framework开发的用户详情API接口路径为localhost/users/profile,配置权限为仅登录用户可访问。用户在后端完成登录后,直接通过后端调用该接口可正常返回数据,正常调用效果如下:
通过React前端发起同接口请求时调用失败,初步判断为前端请求未携带已存储的认证Cookie,需要定位具体原因并修复。
现有React端代码
import React, { useEffect, useState } from "react" import AuthContext from '../context/AuthContext' import {Link} from 'react-router-dom' const ProfilePage = () => { const [profiles, setProfiles] = useState([]) const fetchData = async () => { const response = await fetch("http://127.0.0.1:8000/users/profile") const data = await response.json() setProfiles(data) console.log(data) } useEffect(() => { fetchData() }, []) return ( <div> {profiles.length > 0 && ( <ul> {profiles.map(profile => ( <li key={profile.id}>{profile.name}</li> ))} </ul> )} </div> ) } export default ProfilePage
报错信息
- 浏览器控制台报错:

- 后端服务报错:

解决方案
问题本质是跨域场景下的Cookie携带配置缺失,前后端都需要做对应调整:
前端修改
浏览器默认在跨域fetch请求中不携带Cookie,需要手动给请求添加credentials配置,修改fetchData方法中的请求逻辑:
const fetchData = async () => { const response = await fetch("http://127.0.0.1:8000/users/profile", { credentials: 'include' // 强制跨域请求携带域下存储的认证Cookie }) const data = await response.json() setProfiles(data) console.log(data) }
如果后续你用axios发请求,需要统一配置
axios.defaults.withCredentials = true,效果一致。
后端配置
Django侧需要配置CORS规则允许凭证跨域请求,否则浏览器会直接拦截后端返回的响应:
- 先安装跨域处理依赖:
pip install django-cors-headers - 修改项目
settings.py配置:
# 注册corsheaders到INSTALLED_APPS INSTALLED_APPS = [ # 保留原有其他app配置 'corsheaders', ] # 添加CorsMiddleware到中间件列表,注意必须放在django.middleware.common.CommonMiddleware之前 MIDDLEWARE = [ # 保留原有其他中间件配置 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ] # 配置允许跨域访问的前端源,React本地开发默认运行在3000端口,按实际情况修改 CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "http://127.0.0.1:3000", ] # 核心配置:允许跨域请求携带Cookie凭证 CORS_ALLOW_CREDENTIALS = True # 配置CSRF信任源,避免Django拦截带凭证的跨域请求 CSRF_TRUSTED_ORIGINS = [ "http://localhost:3000", "http://127.0.0.1:3000", ]
- 确认DRF的认证类配置包含Session认证(默认自带,如果你之前修改过需要确认):
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', # 其他你正在使用的认证类可保留 ] }
配置完成后重启Django服务,刷新前端页面重新登录后再调用接口即可正常返回数据。如果还是存在Cookie不携带的问题,可在settings.py中补充Cookie配置适配本地开发场景:
SESSION_COOKIE_SAMESITE = 'Lax' # 本地开发不需要开Secure,生产环境HTTPS下需要开启 # SESSION_COOKIE_SECURE = True
内容的提问来源于stack exchange,提问作者Khal Shaphat
相关产品推荐
相关产品推荐

