Twilio X-Twilio-Signature签名验证失败问题求助
以下是排查和解决该问题的关键步骤:
严格匹配Webhook URL
Twilio生成签名时依赖的URL必须和你传入validate方法的URL完全一致,包括协议(http/https)、域名、端口(非标准端口必须带上)、路径,甚至查询参数的顺序和内容都不能错。比如Twilio后台配置的是https://your-app.com/twilio/webhook,你代码里传http://your-app.com/twilio/webhook或者多了个尾斜杠https://your-app.com/twilio/webhook/都会导致验证失败。如果用了反向代理,要确保代理转发后的URL和Twilio配置的完全一致。请求体必须完全匹配原始格式
- 用
String类型的body参数时,必须直接使用Twilio发送的原始application/x-www-form-urlencoded格式字符串,不能转成JSON、不能修改字符编码、不能额外添加或删除任何字符(包括空格、换行)。 - 用
Map<String, String>参数时,要保证Map中的键值对和Twilio发送的完全一致(键都是小写,比如from、to),且Twilio生成签名时会按参数名的ASCII升序排序,你构造的Map也要保持这个顺序,或者直接用原始表单字符串更稳妥。 - 注意Spring Boot中如果用
@RequestBody接收JSON会自动解析,但Twilio发送的是表单数据,应该用@RequestParam或者直接读取原始请求体流,避免解析过程中修改了内容。
- 用
确认Auth Token正确
初始化RequestValidator时必须传入你Twilio账号对应的Auth Token,不能用Account SID或者其他错误的凭证。代码示例:String twilioAuthToken = "你的真实Auth Token"; RequestValidator validator = new RequestValidator(twilioAuthToken);处理带查询参数的URL
如果你的Webhook URL包含查询参数(比如https://your-app.com/webhook?source=twilio),Twilio生成签名时会包含这些参数,所以你传入validate的URL必须完整带上这些参数,且参数名要按ASCII升序排列(和Twilio生成签名的逻辑一致)。检查编码一致性
确保你的应用用UTF-8编码处理请求体,Twilio发送的请求默认是UTF-8编码,若代码用了其他编码(如GBK),会导致body内容失真,签名验证失败。调试验证参数
打印出你传入validate的三个参数:URL、body、X-Twilio-Signature值,然后和Twilio发送的原始请求对比(可以用ngrok日志、Spring Boot的请求日志工具查看原始请求内容),确认三者和Twilio发送的完全匹配。
内容的提问来源于stack exchange,提问作者jvx23

