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

Heroku部署环境下Node应用无法设置Cookie求助

生产环境下Node后端无法给React应用设置Cookie的问题

我的React应用部署在xxx.herokuapp.com,Node后端部署在yyy.herokuapp.com,二者均可正常运行,后端也能向前端传输数据,但无法设置Cookie。该功能在本地环境完全正常,生产环境下失效。我已使用cookieParser处理Cookie,相关代码如下:


后端配置代码(index.js)

app.use(
  cors({
    origin: [
      "http://localhost:3000",
      "https://xxx.herokuapp.com",
      "https://yyy.herokuapp.com",
    ],
    credentials: true,
  })
);

登录接口代码(auth.js)

export const signin = async (req, res, next) => {
  try {
    const user = await User.findOne({ username: req.body.username });
    if (!user) return next(createError(404, "User does not exist!"));

    const verifyPassword = bcrypt.compareSync(req.body.password, user.password);
    if (!verifyPassword) return next(createError(400, "Invalid credentials!"));

    const token = jwt.sign({ id: user._id }, process.env.JWT_KEY);
    const { password, ...others } = user._doc;

    res
      .cookie("access_token", token, {
        httpOnly: true,
      })
      .status(200)
      .json(others);
  } catch (error) {
    next(error);
  }
};

前端登录请求代码(React)

const handleLogin = async (e) => {
    e.preventDefault();
    dispatch(loginStart);

    try {
      setOpen(true);
      setAlert({ message: "Logged in.", severity: "success" });
      const res = await axios.post(`${SERVER_URL}/auth/signin`, userForm, {
        withCredentials: true,
      });
      dispatch(loginSuccess(res.data));
      navigate("/");
      // window.location.href = "/";
    } catch (error) {
      dispatch(loginFailure());
      setOpen(true);
      setAlert({
        message: error.response.data.message,
        severity: "error",
      });
    }
  };

问题排查与解决步骤

  1. 补充Cookie的生产环境必填属性
    生产环境(Heroku为HTTPS环境)下,浏览器的安全策略要求跨域Cookie必须配置secure: true和sameSite: "none",否则会拒绝存储。修改res.cookie配置:

    res
      .cookie("access_token", token, {
        httpOnly: true,
        secure: process.env.NODE_ENV === "production", // 仅生产环境启用
        sameSite: process.env.NODE_ENV === "production" ? "none" : "lax", // 跨域场景需设为none
        domain: ".herokuapp.com" // 可选,确保子域共享Cookie,按需调整
      })
      .status(200)
      .json(others);
    
  2. 修正CORS配置细节

    • 确保origin数组中的前端地址为HTTPS协议(Heroku部署的应用默认是HTTPS),不要写HTTP;
    • 可改为动态判断origin,避免硬编码:
      app.use(cors({
        origin: function(origin, callback){
          const allowedOrigins = ["http://localhost:3000", "https://xxx.herokuapp.com"];
          if(!origin || allowedOrigins.includes(origin)){
            callback(null, true);
          } else {
            callback(new Error("Not allowed by CORS"));
          }
        },
        credentials: true
      }));
      
  3. 确认前端请求配置

    • 确保SERVER_URL是HTTPS的后端地址,不要使用HTTP;
    • 确认withCredentials: true已正确设置,这是前端携带Cookie的必要配置。
  4. 启用Heroku的代理信任
    Heroku的Node应用需要启用trust proxy,否则后端无法正确识别请求协议(HTTP/HTTPS),导致secure属性判断错误。在app.use(cors())之前添加:

    app.set("trust proxy", 1);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:24:27