Symfony+Mercure环境下JS EventSource不发送Cookie导致私有Hub订阅失败
排查与修复步骤
核心问题为跨域场景下Cookie的存储、携带规则配置不完整,按以下顺序修改即可:
1. 修正前端授权请求配置
跨域fetch请求默认不会携带凭证,也不会存储响应返回的Cookie,需要手动开启credentials配置:
// 修改授权接口请求代码 const res = await fetch("http://mydemoapp.com:80/api/v1.0/ms-security/authorization", { method: "GET", headers: {'Authorization': `Bearer ${dataAuth.token}`}, credentials: 'include' // 新增该行,允许跨域请求携带/存储凭证 });
2. 调整Mercure授权Cookie属性
默认生成的Cookie域、路径、SameSite配置不符合跨域使用要求,手动修改Cookie参数:
// 修改授权路由控制器代码 $cookie = $authorization->createCookie($request, ["http://mydemoapp.com:80/api/v1.0/ms-security/23"]); // 手动配置Cookie属性 $cookie = $cookie ->withDomain('mydemoapp.com') // 匹配Mercure服务域名 ->withPath('/.well-known/mercure') // 仅在请求Mercure接口时携带Cookie ->withSameSite('Lax') // 本地HTTP环境用Lax,生产HTTPS环境可设为None并开启secure ->withSecure(false); // 本地HTTP环境设为false,生产HTTPS环境需改为true $response->headers->setCookie($cookie);
3. 补充Caddyfile跨域凭证配置
Mercure默认禁止跨域请求携带凭证,需要在Caddy配置中显式开启:
mercure { demo publisher_jwt MySecretKeyJWT subscriber_jwt MySecretKeyJWT cors_origins http://127.0.0.1:3005 cors_allow_credentials # 新增该行,允许跨域请求携带Cookie anonymous subscriptions }
4. 可选本地开发优化
本地开发时可修改系统hosts文件,将mydemoapp.com指向127.0.0.1,前端改用http://mydemoapp.com:3005访问,彻底规避跨域Cookie限制。
验证方式
修改完成后先清理浏览器原有Cookie,再重新走登录授权流程:
- 打开浏览器开发者工具Application面板,确认
mydemoapp.com域下存在mercureAuthorizationCookie - 查看EventSource请求的Request Headers,确认携带了该Cookie,且Origin值为配置的允许跨域地址
- 确认推送消息时的topic与订阅topic完全一致,无路径拼写错误
内容的提问来源于stack exchange,提问作者Stollpy
相关产品推荐
相关产品推荐

