You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含查询字符串的Twilio Webhook签名验证403失败求助

问题描述

发送Twilio SMS时使用带查询字符串的状态回调URL:

const TwilioClient = Twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);

TwilioClient.messages.create({
    body: message,
    from: fromNumber,
    to: toNumber,
    statusCallback: 'https://example.com/webhook/twilio?id=12345',
});

使用Twilio Express中间件处理请求并验证签名:

router.post(
    '/twilio',
    twilio.webhook({
        authToken: process.env.TWILIO_AUTH_TOKEN,
        host: 'example.com',
        validate: true,
    }),
    async (req, res) => { /* ... */ },
);

带查询字符串时请求返回403,去掉后验证正常。断点发现中间件用带查询字符串的URL验证,但尝试多种URL变体仍无法解决,使用twilio包v4.12.0版本。

解决方案

问题出在Twilio签名验证依赖完整请求URL(含查询字符串),但默认的Express中间件构造验证URL时会忽略查询参数,导致签名不匹配。只需配置getUrl自定义函数,让中间件使用请求的完整URL进行验证:

router.post(
    '/twilio',
    twilio.webhook({
        authToken: process.env.TWILIO_AUTH_TOKEN,
        host: 'example.com',
        validate: true,
        // 自定义获取验证用URL的逻辑
        getUrl: (req) => {
            return `https://${req.headers.host}${req.originalUrl}`;
        }
    }),
    async (req, res) => { /* ... */ },
);

req.originalUrl会保留请求的完整路径(包括查询字符串),结合请求头里的host构造出和Twilio发送时一致的URL,就能通过签名验证。

如果你的部署环境使用非标准HTTPS端口(比如本地测试的3000端口),可以根据实际情况调整URL的协议和端口部分。


内容的提问来源于stack exchange,提问作者asportnoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 02:52:38