Lemonsqueezy Webhook x-signature验证持续失败问题求助
解决Lemonsqueezy Webhook签名验证失败问题
你的签名验证失败核心原因是:使用express.json()解析请求体后,再通过JSON.stringify(req.body)生成的字符串,和Lemonsqueezy发送的原始请求体格式不一致。JSON.stringify()会改变键的排序、空格缩进等细节,而Lemonsqueezy是基于原始未修改的JSON payload生成签名的,这就导致两边的签名无法匹配。
修正方案
改用express.raw()中间件获取原始请求体,直接用原始数据生成签名,再解析为JSON处理业务逻辑:
app.post('/lemonsqueezy-webhook', express.raw({ type: 'application/json' }), (req, res) => { try { const secret = 'THIS IS MY SECRET'; // 基于原始请求体生成HMAC签名 const hmac = crypto.createHmac('sha256', secret); const expectedSignature = Buffer.from(hmac.update(req.body).digest('hex'), 'utf8'); const signature = Buffer.from(req.headers['x-signature'] || '', 'utf8'); console.log('signature:', signature.toString()); console.log('expectedSignature:', expectedSignature.toString()); if (!signature.equals(expectedSignature)) { console.error('Invalid signature received:', signature); return res.status(401).send('Invalid signature'); } else { console.log('Valid signature confirmed:', signature); } // 将原始请求体解析为JSON对象处理业务 const data = JSON.parse(req.body); if (data.meta.event_name === 'subscription_created') { console.log(`New subscription created for user: ${data.data.attributes.user_email}, Subscription ID: ${data.data.id}`); } res.status(200).send('Webhook received'); } catch (error) { console.error('Error in signature verification:', error); res.status(500).send('Server error'); } });
额外排查要点
- 确认密钥完全一致:检查Lemonsqueezy后台配置的密钥和代码中的
secret是否完全匹配,包括大小写、空格、特殊字符,避免复制时出现冗余字符或缺失 - 时间差不影响验证:签名生成只依赖请求体和密钥,和服务器时间无关,无需担心时间差异问题
- 排查中间件干扰:确保该路由没有其他中间件(如日志、格式化类中间件)修改原始请求体,避免签名计算的数据源被篡改
内容的提问来源于stack exchange,提问作者user24707899
相关产品推荐
相关产品推荐

