Django与React跨请求Session异常:vendor_data键缺失报错
Django DRF跨视图读取Session出现KeyError问题
问题重现
我在DRF视图中尝试将字典vendor_data存入request.session:
class MyClass(APIview): def post(self, request, format=None): request.session['vendor_data'] = vendor_data # 这是一个字典
之后在另一个DRF视图中读取该键:
class AnotherClass(APIview): def post(self, request, format=None): vendor_data = request.session['vendor_data']
执行时抛出KeyError,提示缺少"vendor_data"键。
环境与配置背景
- API部署在开放端口的EC2实例,请求来自本地PC的localhost React环境
- Django settings.py核心配置:
ALLOWED_HOSTS = ['*'] CORS_ALLOW_CREDENTIALS = True CORS_ALLOWED_ORIGINS = [ 'http://localhost:3002', # React应用端口 'http://127.0.0.1:3002', 'http://10.0.90.2:8008', # 测试Django应用端口 'http://127.0.0.1:8008', 'http://localhost:8008', ] SESSION_COOKIE_SECURE = False SESSION_COOKIE_AGE = 300 SESSION_ENGINE = 'django.contrib.sessions.backends.db' SESSION_COOKIE_SAMESITE = 'None'
业务场景是通过OTP完成用户注册认证,验证OTP前需要将用户信息存在session中,但当前报错导致无法完成验证。
补充:React请求代码
try { console.log("Submitting OTP:", otp); const response = await axios.post( "http://IP:8008/api/otp-verification/", { otp: String(otp) }, // 确保OTP以字符串形式传递 { headers: { "Content-Type": "application/json", // Authorization: `Bearer ${token}`, // 使用token时取消注释 }, withCredentials: true, } ); console.log("Response:", response); if (response.status === 200) { alert("OTP verified successfully!"); localStorage.removeItem('otp'); // 可选:从localStorage移除OTP navigate("/Login"); // 验证成功后跳转到登录页 } } catch (error) { console.error("OTP verification failed:", error.response ? error.response.data : error.message); // 根据响应处理特定错误信息 if (error.response && error.response.data) { setErrorMessage(error.response.data.message || "Invalid OTP. Please try again."); } else { setErrorMessage("An error occurred. Please try again later."); } } finally { // 请求完成后隐藏加载状态 setLoading(false); } };
解决方案
- 手动保存Session修改
DRF默认不会自动保存session的修改,在写入session的视图中添加request.session.save():
class MyClass(APIview): def post(self, request, format=None): request.session['vendor_data'] = vendor_data request.session.save() # 强制保存session
- 安全读取Session键
使用get方法避免直接取值抛出KeyError,同时添加日志排查:
class AnotherClass(APIview): def post(self, request, format=None): vendor_data = request.session.get('vendor_data') if not vendor_data: print("Session中无vendor_data键,当前session所有键:", request.session.keys()) return Response({"error": "用户信息不存在,请重新提交"}, status=400) # 后续业务逻辑
- 验证Cookie与CORS配置完整性
- 确认React请求的
withCredentials: true已正确设置(当前代码已配置) - 本地开发环境
SESSION_COOKIE_SAMESITE = 'None'搭配SESSION_COOKIE_SECURE = False是可行的,生产环境需开启SESSION_COOKIE_SECURE = True - 检查
CORS_ALLOWED_ORIGINS是否包含React应用的完整地址,避免跨域Cookie被拦截
- 检查Session存储与网络连通性
- 登录Django后台或直接查询数据库的
django_session表,确认写入session的请求是否生成了对应记录 - 验证EC2安全组是否允许本地PC的IP访问8008端口,避免请求未到达服务端
内容的提问来源于stack exchange,提问作者rahul.dey
相关产品推荐
相关产品推荐

