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

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);
    }
  };

解决方案

  1. 手动保存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
  1. 安全读取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)
        # 后续业务逻辑
  1. 验证Cookie与CORS配置完整性
  • 确认React请求的withCredentials: true已正确设置(当前代码已配置)
  • 本地开发环境SESSION_COOKIE_SAMESITE = 'None'搭配SESSION_COOKIE_SECURE = False是可行的,生产环境需开启SESSION_COOKIE_SECURE = True
  • 检查CORS_ALLOWED_ORIGINS是否包含React应用的完整地址,避免跨域Cookie被拦截
  1. 检查Session存储与网络连通性
  • 登录Django后台或直接查询数据库的django_session表,确认写入session的请求是否生成了对应记录
  • 验证EC2安全组是否允许本地PC的IP访问8008端口,避免请求未到达服务端

内容的提问来源于stack exchange,提问作者rahul.dey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:21:02