使用Adonis.js开发Stripe Webhook验证中间件持续报错求助
排查Adonis.js中Stripe Webhook签名验证失败的问题
我之前在Adonis.js里处理Stripe Webhook签名验证时也踩过类似的坑,结合你的代码,几个关键排查点和解决方案可以参考:
1. 确保请求体未被篡改(核心问题)
Stripe的签名验证完全基于原始未解析的请求体生成,如果Adonis默认的bodyparser中间件提前解析了请求体,再通过request.raw()拿到的内容会和Stripe发送的原始数据不一致,直接导致签名匹配失败。
解决方法:
- 在Webhook路由定义中禁用bodyparser:
// 以Adonis v5为例,路由文件中配置 Route.post('/stripe/webhook', 'StripeWebhookController.handle') .middleware(['stripe-webhook']) .disableBodyParser();
- 正确获取原始请求体:
- Adonis v4:直接使用
request.raw() - Adonis v5:需要异步获取
await request.rawBody()
- Adonis v4:直接使用
2. 检查签名密钥的获取逻辑
你的代码里根据事件类型webhookEvent拼接密钥,但Stripe的Webhook签名密钥是绑定到具体的Webhook端点(URL),而非单个事件类型的。如果你的配置逻辑是按事件类型分配密钥,大概率会用错密钥导致验证失败。
如果确实需要按事件类型区分,要注意顺序:禁用bodyparser后request.post().type无法直接获取事件类型,得先完成签名验证,再解析事件体拿到类型:
const rawBody = await request.rawBody(); // 或request.raw() const signature = request.header('stripe-signature'); // 先使用端点对应的通用密钥验证 const signingSecret = Config.get('stripe.webhook_secret'); try { const event = Stripe.webhooks.constructEvent(rawBody, signature, signingSecret); // 验证通过后再获取事件类型 const webhookEvent = event.type; // 后续业务逻辑... request.stripeEvent = event; await next(); } catch (err) { console.error('Stripe验证错误详情:', err.message); return response.status(400).send(`Webhook Error: ${err.message}`); }
3. 添加错误捕获,明确失败原因
你当前的代码没有捕获constructEvent抛出的错误,根本不知道是签名不匹配、密钥错误还是签名过期等具体问题。添加try-catch后,控制台会输出详细错误信息,帮你快速定位问题。
额外验证步骤
- 确认Stripe Dashboard中配置的Webhook端点URL和你本地/服务器的URL完全一致(包括http/https)
- 确认Stripe Dashboard里的签名密钥和你配置文件中的
whsec_xxxx完全一致,没有空格或拼写错误
内容的提问来源于stack exchange,提问作者Tallgeese
相关产品推荐
相关产品推荐

