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

MERN JWT认证应用部署后客户端Cookie无法设置问题

MERN栈JWT认证应用部署后Cookie无法设置问题

我开发了一个基于MERN栈的JWT认证应用,服务器部署在https://api.somanyu.tech,客户端部署在https://finapp.somanyu.tech,二者均托管于Render并使用get.tech域名。

问题:客户端无法设置Cookie,浏览器中仅显示Cloudflare的__cf_bm、_cfuvid Cookie,预期的Token Cookie未出现。

后端设置Cookie代码(authController.js)

// Generate JWT Token.
const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET, {
  expiresIn: "36h",
});

console.log("GENERATED TOKEN\n", token);

if (req.cookies[`${user._id}`]) {
  req.cookies[`${user._id}`] = "";
}

// Set cookie.
res.cookie(String(user._id), token, {
  httpOnly: true,
  path: '/*',
  expires: new Date(Date.now() + 100 * 30),
  maxAge: 1000 * 60 * 60 * 24 * 7,
  sameSite: 'none',
  domain: 'finapp.somanyu.tech',
  secure: true,
});

return res.status(201).send({ success: "Signed in successfully." });

Token验证中间件代码(authMiddleware.js)

const verifyToken = async (req, res, next) => {

    // Retrieve cookies from header.
    const cookies = req.headers.cookie;
    console.log("🚀 ~ file: authMiddleware.js:7 ~ verifyToken ~ cookies:", cookies)
    if (cookies) {
        const cookie = cookies.split("=")[1];
        const token = jwt.verify(cookie, process.env.JWT_SECRET, (error, user) => {
            if (error) return res.status(401).json({ error: "Invalid Token" });
            req.user = user._id; // Id of the user who is logged in.
            next();
        });
    } else {
        return res.status(401).json({ error: "No Token" });
    }
}

本地环境一切正常,但部署后Cookie无法存储到浏览器。已确认Token可正常生成,但req.headers.cookie中仅存在Cloudflare的Cookie。这是我首次部署MERN应用,可能遗漏了关键步骤。


问题根源及修复方案

1. Cookie域名配置错误

服务器域名是api.somanyu.tech,设置Cookie时指定domain: 'finapp.somanyu.tech'属于跨域操作,浏览器会直接拒绝。正确做法是将domain设为父域名.somanyu.tech,这样两个子域名都能访问该Cookie;或者直接删除domain配置,让浏览器自动匹配当前服务器域名(需配合客户端跨域凭证配置)。

2. expires与maxAge冲突

代码中同时设置了expires和maxAge,且expires仅设置了30秒有效期,会导致Cookie立即过期。保留maxAge即可(建议和JWT的expiresIn保持一致,比如36小时),删除expires配置。

3. 客户端跨域请求未携带凭证

客户端发送登录请求时,必须开启凭证携带:

  • Axios需配置withCredentials: true
  • Fetch需设置credentials: 'include'
    否则浏览器不会保存跨域设置的Cookie。

4. 后端CORS配置缺失

服务器必须配置CORS允许携带凭证,示例代码:

const cors = require('cors');
app.use(cors({
  origin: 'https://finapp.somanyu.tech',
  credentials: true,
  allowedHeaders: ['Content-Type']
}));

注意origin不能设为*,必须指定具体的客户端域名,否则浏览器会拒绝携带凭证的请求。

5. Cookie解析逻辑不严谨

中间件中cookies.split("=")[1]的写法会直接取第一个Cookie的值,无法精准获取目标Token。建议使用cookie-parser库简化Cookie读取:

  1. 安装依赖:npm install cookie-parser
  2. 在服务器中启用:app.use(cookieParser())
  3. 中间件中修改为:
const verifyToken = async (req, res, next) => {
  // 假设登录时用user._id作为Cookie名称
  const token = req.cookies[req.user?._id];
  if (!token) return res.status(401).json({ error: "No Token" });

  jwt.verify(token, process.env.JWT_SECRET, (error, user) => {
    if (error) return res.status(401).json({ error: "Invalid Token" });
    req.user = user._id;
    next();
  });
}

修复后的Cookie设置代码示例

res.cookie(String(user._id), token, {
  httpOnly: true,
  path: '/',
  maxAge: 1000 * 60 * 60 * 36, // 和JWT有效期一致(36小时)
  sameSite: 'none',
  domain: '.somanyu.tech', // 父域名共享Cookie
  secure: true,
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:25:32