Meta开发者控制台message_template_status_update Webhook验证失败求助
问题分析与解决方案
你的问题出在签名验证时使用了Laravel解析后的请求数组转JSON,而非原始请求体的字节内容。Meta的Webhook签名是基于POST请求的原始未修改的请求体计算的,而$request->all()会将请求体解析为数组,再用json_encode()序列化时,可能会改变原始请求的键顺序、空格、转义格式,导致哈希值不匹配——这也是为什么messages能通过(可能刚好序列化后的结果和原始一致),但message_template_status_update不行(请求体结构不同,序列化后和原始差异明显)。
修正后的验证代码
if ($request->hasHeader('x-hub-signature-256')) { $shaSig = $request->header('x-hub-signature-256'); $shaSig = str_replace('sha256=', '', $shaSig); // 使用原始请求体内容,而非解析后的数组 $rawPayload = $request->getContent(); $signature = hash_hmac('sha256', $rawPayload, env('META_APP_SECRET')); if (hash_equals($shaSig, $signature)) { // 验证通过,处理业务逻辑 } else { // 验证失败 } }
额外注意事项
- 不要对原始请求体做任何修改(比如去除空格、转义字符),直接使用
$request->getContent()获取的内容即可。 - 建议使用
hash_equals()代替==做字符串比较,避免时序攻击风险。 - 确认
META_APP_SECRET配置正确,且和Meta开发者后台中应用的密钥完全一致(messages能验证通过,这点大概率没问题,但可以再核对一次)。
内容的提问来源于stack exchange,提问作者Karthik07
相关产品推荐
相关产品推荐

