
本文详解 Viber Bot 回调签名(HMAC-SHA256)的正确生成方法,指出常见错误根源——原始 JSON 负载必须以原始字节流(raw body)参与签名,而非经 json_decode 或字符串美化处理后的结果,并提供可直接运行的 PHP 示例与关键注意事项。
本文详解 viber bot 回调签名(hmac-sha256)的正确生成方法,指出常见错误根源——原始 json 负载必须以**原始字节流(raw body)**参与签名,而非经 `json_decode` 或字符串美化处理后的结果,并提供可直接运行的 php 示例与关键注意事项。
Viber 官方要求回调签名使用 HMAC-SHA256 算法,以 Bot 的 Authentication Token 为密钥,对 原始 HTTP 请求体(raw request body) 进行哈希计算。关键点在于:不能对已解析、重格式化或 json_encode 生成的 JSON 字符串签名,而必须严格使用 Viber 服务器发送的原始字节流(即未改动的 file_get_contents('php://input') 或 $request->getContent() 返回值)。
你提供的示例中,虽然调用了 $request->getContent(),但问题极可能出在 Laravel 框架的中间件(如 ValidateJsonContent、TrimStrings 或 ConvertEmptyStringsToNull)或请求预处理逻辑中——这些机制可能已对原始 body 做了隐式解码、空格归一化或 UTF-8 BOM 清理,导致输入字节与 Viber 发送的原始 JSON 不一致。
✅ 正确做法如下(Laravel 环境推荐):
public function index(Request $request)
{
// ✅ 关键:获取原始、未经任何处理的请求体字节流
$rawBody = file_get_contents('php://input');
// ✅ 密钥为 Viber 提供的完整 Authentication Token(含连字符)
$token = '4453b6ac12345678-e02c5f12174805f9-daec9cbb5448c51f';
// ✅ 使用 hash_hmac,输出为十六进制小写字符串(Viber 验证时默认比对此格式)
$signature = hash_hmac('sha256', $rawBody, $token);
return response($signature)->header('Content-Type', 'text/plain');
}
⚠️ 注意事项:
-
禁用自动 JSON 解析中间件:确保该路由不经过
App\Http\Middleware\ConvertEmptyStringsToNull、TrimStrings等可能修改原始 body 的中间件;可在app/Http/Kernel.php中为该路由单独配置中间件组,或使用php://input绕过 Laravel 的请求解析流程。 -
不要
json_decode后再json_encode:即使你尝试“标准化” JSON 结构(如排序键、移除空格),也会改变字节序列,导致签名不匹配。 -
验证签名时区分大小写与编码:Viber 返回的
X-Viber-Content-Signature头是小写十六进制字符串,你的计算结果也必须是小写(hash_hmac默认满足)且无前缀。 -
检查请求头是否含 BOM 或额外换行:某些代理或调试工具可能注入不可见字符,建议用
bin2hex($rawBody)打印前 32 字节进行比对。
? 补充验证技巧:将 Viber 文档中给出的示例 JSON(含精确空格与换行)保存为 test.json,用命令行验证签名一致性:
# Linux/macOS cat test.json | openssl dgst -hmac "4453b6ac12345678-e02c5f12174805f9-daec9cbb5448c51f" -sha256 | sed 's/.* //'
输出应与预期 9d3941b33d45c165400d84dba9328ee0b687a5a18b347617091be0a56d 完全一致(注意:Viber 官方示例末尾少写了 1 位,实际应为 64 位 hex;此处以你提供的“Correct Result”为准,但建议以 官方文档最新版 或实际抓包为准)。
遵循上述原则,即可稳定生成与 Viber 服务端完全一致的回调签名,确保消息事件(如 delivered、seen、message)的安全可信验证。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











