frankenphp的mercure hub必须由代理层统一签发jwt,禁用匿名访问,频道命名需与jwt白名单严格对齐租户前缀,cli任务须显式传入tenant_id确保隔离。

Mercure Hub 的 JWT 认证必须由 FrankenPHP 代理层统一签发
FrankenPHP 自带的 Mercure 集成不是“开箱即用”的匿名广播通道,它默认启用 JWT 验证,且 hub.publish 和 hub.subscribe 的权限完全取决于你签发的 JWT 中的 mercure 声明。如果你直接把前端 Mercure SDK 指向 /.well-known/mercure 并自己生成 token,就等于绕过 FrankenPHP 的租户上下文,权限隔离立刻失效。
实操建议:
- 所有 JWT 必须由 PHP 后端(如控制器)调用
frankenphp_mercure_generate_token()或手动构造,不能在 JS 里用密钥硬编码生成 - token 必须包含
"mercure": {"subscribe": ["user:123", "tenant:abc123"]}这类明确前缀的频道白名单,禁止用通配符*或空数组 - 订阅时前端 Mercure SDK 的
topics参数必须与 JWT 中subscribe列表严格匹配——例如传['user:123'],但 token 里只写了["tenant:abc123"],订阅会静默失败 - 不要复用登录态 JWT:用户登录 token 通常不含
mercure声明,需单独签发带 Mercure 权限的短期 token(建议有效期 ≤ 5 分钟)
频道命名必须带租户/用户粒度前缀,且与 JWT 白名单对齐
Mercure 本身不识别租户概念,它只做字符串匹配。如果你的频道是 /api/orders/456,而 JWT 允许的是 user:123,那这个订阅根本不会被授权——因为频道名和白名单项不一致。
正确做法是让频道名和 JWT 白名单共享同一套命名空间:
- ✅ 推荐格式:
tenant:abc123:order_updated、user:789:notification、room:xyz:chat - ❌ 错误示例:
/orders/456(路径式命名无法与 JWT 关联)、abc123_order_updated(缺标准分隔符,ACL 规则难写) - JWT 中的
subscribe字段必须精确包含这些字符串,比如["tenant:abc123:.*", "user:789:.*"]可用正则,但生产环境更推荐显式枚举,避免误匹配 - 后端发布时,
publish()调用的频道名必须和前端订阅的一致,否则消息进不了目标客户端
FrankenPHP 的 hub 配置必须禁用匿名访问并校验 JWT 签名
默认配置下,FrankenPHP 的 Mercure hub 可能允许未认证请求(尤其开发环境),这会让租户隔离形同虚设。你必须显式关闭匿名模式,并强制验证签名。
检查 frankenphp.yaml 或 Caddyfile 中的 Mercure 配置:
- 确认存在
anonymous: false(或等效的allow_anonymous: false) -
publish_origins应限制为可信后端域名(如https://api.example.com),禁止* -
jwt_key必须是强随机字符串(至少 32 字节),且不能写死在前端或日志里;建议从环境变量读取:jwt_key: ${MERCURE_JWT_KEY} - 若使用自定义 JWT 签发逻辑,确保使用 HS256 算法且 key 与 hub 配置完全一致,否则会出现
Invalid JWT signature错误
CLI/队列任务发布 Mercure 消息时,必须手动注入租户上下文
这是最容易被忽略的隔离断点:当订单超时取消、定时报表生成等任务在 CLI 或队列中运行时,没有 HTTP 请求上下文,tenant_id 不会自动存在。如果这时调用 publish() 且没指定频道前缀,消息可能发到全局频道,被所有租户收到。
实操要点:
- 队列任务执行前,必须通过参数或上下文传递
tenant_id,例如 Laravel 的dispatch(new OrderTimeoutJob($order->tenant_id)) - 发布代码中禁止出现硬编码频道名,必须拼接:
"tenant:{$tenantId}:order_timeout" - 不要依赖中间件或请求对象获取
tenant_id—— CLI 环境里request()或app('tenant')会报错或返回 null - 可在任务基类中统一封装
mercurePublish()方法,强制要求传入$tenantId参数,否则抛出异常
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











