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

配置NGINX子域名后MERN应用401未授权(JWT Cookie未设置)

MERN应用子域名部署后JWT Cookie无法设置导致401问题排查

我用DigitalOcean、Nginx和PM2部署了MERN应用,直接通过服务器IP访问一切正常,但配置Nginx子域名(api.example.com作为后端,example.com作为前端)后,需要JWT验证的API请求出现401 Unauthorized错误。检查发现,存储JWT的access_token_client Cookie根本没在浏览器里设置,Chrome开发者工具里也找不到这个Cookie。

已经尝试过的配置:

  • 在server/index.js中配置CORS,开启credentials: true,并允许http://example.com、http://www.example.com、http://admin.example.com这些源;
  • 修改后端登录接口控制器,设置Cookie参数:httpOnly: true、secure: false、sameSite: 'none'、domain: '.example.com';
  • 修改Nginx配置,添加了代理相关头信息;
  • 前端Login.jsx里给axios实例加上了withCredentials: true。

登录接口能正常返回,服务器日志也显示Set-Cookie头已经设置,但后续需要验证Token的API请求中,后端的verifyToken中间件从req.cookies里拿不到Token,最终导致401错误。


可能的原因及解决方法

1. Nginx代理未正确传递Cookie属性

Nginx反向代理时,默认可能会修改或丢失Set-Cookie头的关键配置,导致浏览器无法识别。检查你的api.example.com Nginx配置文件,确保添加以下代理配置:

location / {
    proxy_pass http://localhost:你的后端端口;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    # 强制替换Cookie的域名和路径,适配子域名场景
    proxy_cookie_domain localhost .example.com;
    proxy_cookie_path / /;
}

重点是proxy_cookie_domain,它会把后端返回的localhost域名替换成.example.com,让浏览器能将Cookie绑定到主域名下,所有子域名都能访问。

2. Secure属性与网站协议不匹配

如果你的网站已经配置了HTTPS(比如用Let's Encrypt证书),secure: false会导致浏览器拒绝存储Cookie——HTTPS环境下,浏览器要求Cookie必须开启secure: true才能生效。

修改后端Cookie配置:

res.cookie('access_token_client', token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production', // 生产环境自动设为true
    sameSite: 'none',
    domain: '.example.com',
    maxAge: 24 * 60 * 60 * 1000 // 按需设置有效期
});

注意:sameSite: 'none'必须配合secure: true使用,否则浏览器会直接忽略这个Cookie。

3. CORS允许源与实际访问地址不匹配

检查CORS配置里的源是否和前端实际访问的地址完全一致(包括协议http/https)。比如前端用https://example.com访问,但你CORS只允许了http://example.com,这会直接导致Cookie无法跨域设置。

更新CORS配置:

const corsOptions = {
    credentials: true,
    origin: [
        'https://example.com',
        'https://www.example.com',
        'https://admin.example.com'
    ]
};
app.use(cors(corsOptions));

生产环境建议明确指定允许的源,避免用通配符*(通配符和credentials: true冲突)。

4. SameSite属性的兼容性问题

sameSite: 'none'是跨域场景的正确配置,但部分旧浏览器不支持,且必须配合secure: true。如果是本地http环境测试,可以临时将sameSite改为'lax'或'strict',生产环境再改回'none'。

5. 浏览器第三方Cookie拦截设置

检查浏览器是否开启了“阻止第三方Cookie”(比如Chrome的隐私设置)。虽然主域名和子域名属于同一站点,但部分严格的隐私策略可能会影响Cookie存储。可以先临时关闭该设置测试,若恢复正常,再考虑调整Cookie属性或引导用户修改浏览器设置。

6. Cookie域名格式错误

确保domain: '.example.com'的格式正确,前面的点不能省略——这种格式能让Cookie被主域名(example.com)和所有子域名(api.example.com等)共享。如果写成domain: 'example.com',部分浏览器可能只会将Cookie绑定到主域名,子域名无法访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 10:43:28