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

NodeJs后端与React前端远程环境Cookie参数设置异常排查

问题描述

  • 需求:后端在Cookie中设置并修改名为Myparameter的参数
  • 现象:
    • Postman测试时,本地和远程环境均可正常设置Cookie
    • 浏览器页面操作时,仅本地环境生效,远程后端无法更新Cookie中的Myparameter
  • 补充:浏览器控制台网络标签可见Cookie,但仅本地环境的Storage Cookie中显示;尝试Postman生成的Fetch代码,仍无效

后端代码(Node.js + Express)

var express = require('express');
const cookieParser = require('cookie-parser');
var cors = require('cors');
let bodyParser = require('body-parser');
const sessions = require('express-session');

var app = express();
app.use(cookieParser());
app.use(cors({ origin: ['http://localhost:3000', 'http://REMOTE_IP:3000'], credentials: true, exposedHeaders: ["set-cookie"] }));
app.use(express.json());
//app.set("trust proxy", 1);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.urlencoded({ extended: true }));

//const oneDay = 1000 * 60 * 60 * 24;
const two_min_session = 1000 * 120;

app.use(session1 = sessions({
    name: "cookie_session1",
    secret: "fgydsanffdsafdsf456845dsfaf4651315641",
    cookie: {
        maxAge: two_min_session,
        httpOnly: true,
        sameSite: 'strict',
        secure: false,
    },
    resave: true,
    saveUninitialized: true,
    sameSite: 'none',
}));

var one_more_cookie = function (req, res) {
    console.log(Date(), "Req", req.body, req.params, req.cookie);
    res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Expose-Headers', 'date, etag, access-control-allow-origin, access-control-allow-credentials');
    res.cookie('refresh_token', 'refresh_token', {
        maxAge: 30 * 24 * 60 * 60 * 1000,
        httpOnly: true,
        sameSite: 'none',
        path: '*/*'
    });
    res.status(200).json("Cookie Sent from Backend");
};
app.post('/api/cookie', cookieParser(), one_more_cookie);

app.post('/api/logincookie', cookieParser(), (req, res) => {
    console.log("Cookies", req.cookies);
    console.log(req.session, req.session);
    res.status(200).send({ 'Reading req': 'Reading req' });
});

app.post('/api/setcookie', cookieParser(), (req, res) => {
    console.log("Session Before", req.session);
    console.log("Cookies Before", req.cookies);
    req.session.Myparameter = "Check";
    console.log("Session After", req.session);
    console.log("Cookies After", req.cookies);
    res.status(200).json({ 'cookie': 'set' });
});

const port = process.env.PORT || 3001;
app.listen(port, function () { console.log('Your app is listening on port ' + port) });

前端代码(React + Axios)

const checkCookie = function () {
  const data = axios.post('http://REMOTE_IP:3000/api/logincookie',
    { withCredentials: true });
}

const setCookie = function () {
  const data = axios.post('http://REMOTE_IP:3000/api/setcookie',
    { withCredentials: true });
}

const getCookie = async () => {
  try {
    const { data } = await axios.post('http://REMOTE_IP:3000/api/cookie',
      { withCredentials: true });
  }
  catch (error) {
    console.log(error);
  }
}

解决方案

1. 修复Session Cookie的跨域配置冲突

远程环境浏览器对跨域Cookie限制更严格,当前Session配置存在冗余和错误:

  • 将cookie.sameSite改为'none'(跨域场景必须设置),删除外层冗余的sameSite: 'none'
  • 生产环境(HTTPS)下开启secure: true,本地HTTP环境保持false
  • 优化resave和saveUninitialized参数,减少不必要的Session存储

修改后的Session配置:

app.use(sessions({
    name: "cookie_session1",
    secret: "fgydsanffdsafdsf456845dsfaf4651315641",
    cookie: {
        maxAge: two_min_session,
        httpOnly: true,
        sameSite: 'none',
        secure: process.env.NODE_ENV === 'production' ? true : false,
    },
    resave: false,
    saveUninitialized: false,
}));

2. 统一CORS配置,删除硬编码Header

one_more_cookie函数中硬编码的Access-Control-Allow-Origin会与CORS中间件冲突,直接删除手动设置的Header,同时修正req.cookie为req.cookies,调整Cookie路径为'/':

var one_more_cookie = function (req, res) {
    console.log(Date(), "Req", req.body, req.params, req.cookies);
    res.cookie('refresh_token', 'refresh_token', {
        maxAge: 30 * 24 * 60 * 60 * 1000,
        httpOnly: true,
        sameSite: 'none',
        secure: process.env.NODE_ENV === 'production' ? true : false,
        path: '/'
    });
    res.status(200).json("Cookie Sent from Backend");
};

3. 修正Axios的withCredentials配置位置

当前代码将withCredentials放在请求data中,需调整为请求config参数:

const checkCookie = function () {
  const data = axios.post('http://REMOTE_IP:3000/api/logincookie', {}, { withCredentials: true });
}

const setCookie = function () {
  const data = axios.post('http://REMOTE_IP:3000/api/setcookie', {}, { withCredentials: true });
}

const getCookie = async () => {
  try {
    const { data } = await axios.post('http://REMOTE_IP:3000/api/cookie', {}, { withCredentials: true });
  }
  catch (error) {
    console.log(error);
  }
}

4. 启用信任代理(远程环境用反向代理时)

如果后端部署在Nginx等反向代理后,开启trust proxy让Express正确识别请求协议:

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

5. 验证Session参数是否生效

Myparameter存储在服务器端Session中,浏览器仅保存Session ID Cookie,可在/api/logincookie接口返回该参数验证:

app.post('/api/logincookie', cookieParser(), (req, res) => {
    console.log("Cookies", req.cookies);
    console.log("Session", req.session);
    res.status(200).send({ 
      'Reading req': 'Reading req',
      'Myparameter': req.session.Myparameter
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:15:53