调用StripeEventUtility.ConstructEvent出现Stripe-Signature无签名异常如何解决
Stripe Webhook 签名校验异常解决方案
报错原文:The signature for the webhook is not present in the Stripe-Signature header
中文释义:Webhook 的签名未出现在 Stripe-Signature 请求头中
常见原因及对应解决方法
- 请求体被提前读取导致负载为空
如果在调用StripeEventUtility.ConstructEvent之前,已经通过JObject转换、模型绑定等方式读取过请求体,会导致后续读取到的负载为空,签名校验自然失败。
解决方案:在请求管道中开启请求体缓冲,允许重复读取请求体,处理时先重置请求体游标位置再读取原始内容。
ASP.NET Core 中开启请求体缓冲的中间件配置:
// Program.cs 中添加,放在路由匹配之前 app.Use(async (context, next) => { context.Request.EnableBuffering(); await next(); });
请求头取值错误
不要手动拆分、修改Stripe-Signature请求头的内容,直接取完整的请求头值传入方法即可,SDK会自动解析头中的时间戳、签名等值。Webhook 密钥不匹配
确认使用的是Stripe Dashboard中对应Webhook端点的专属签名密钥,而非Stripe账户的全局API密钥;同时要区分测试模式和生产模式的密钥,二者不可混用。负载被篡改
不要对原始请求体做任何序列化、转义、格式调整操作,直接读取UTF8编码的原始字符串传入方法即可。如果先将负载转成JObject再序列化回字符串,格式会发生变化,直接导致签名校验失败。
正确代码示例
[HttpPost("stripe-webhook")] public async Task<IActionResult> WebhookHandler() { // 替换为你自己的Webhook签名密钥 const string webhookSecret = "whsec_xxxxxxxxxxxxxxx"; var signatureHeader = Request.Headers["Stripe-Signature"].FirstOrDefault(); // 重置请求体游标,读取原始负载 Request.Body.Position = 0; using var streamReader = new StreamReader(Request.Body, Encoding.UTF8); var rawPayload = await streamReader.ReadToEndAsync(); Request.Body.Position = 0; try { var stripeEvent = StripeEventUtility.ConstructEvent(rawPayload, signatureHeader, webhookSecret); // 此处添加事件处理逻辑 return Ok(); } catch (StripeException) { return BadRequest(); } }
补充说明
如果以上操作都无效,可以尝试将Stripe.net SDK升级到最新稳定版,部分旧版本存在签名校验的已知bug。
内容的提问来源于stack exchange,提问作者Sourabh Dhiman
相关产品推荐
相关产品推荐

