标准做法是,当您向事件通知服务注册端点时,事件通知服务会向您提供一个秘密,然后该服务使用该共享秘密对其发送到您的端点的消息进行签名,以便您的服务器可以验证消息是合法。
但是为什么这是必要的呢?假设您的端点和事件通知服务都使用 HTTPS,那么 HTTPS 是否应该处理您需要的一切,从而使整个秘密和签名过程变得多余?这个想法是不依赖 SSL 证书,还是允许客户端使用非 HTTPS 的端点?
此处的签名秘密是为了确保该事件确实来自 Stripe。签名还与特定时间戳相关联,以避免“重放攻击”。
如果没有秘密,我可以找出或猜测您构建的 webhook 处理程序,例如期望
checkout.session.completed
事件,然后我会向您发送一个假事件 evt_123
,让您给我的付款看起来像是付款成功例如,访问产品。有一些方法可以解决这个问题(很难猜测端点、Stripe IP 地址的允许列表、URL 中的秘密等),但它们都有缺点。
同样,如果我能找到有效的事件的有效负载,我可以重复使用相同的确切有效负载(我知道自从您接受它以来它是有效的)并每天重播它以继续每天访问某些内容。通过 Stripe 构建的 Webhook 签名逻辑,签名与特定时间戳相关联,例如,如果签名超过 10 分钟,您可以拒绝事件。 Stripe 在他们的文档中介绍了这一点这里。
@koopajah 的答案是正确的,但我将对其进行扩展并添加一些解释,解释为什么 HTTPS 在 webhooks 的情况下没有帮助。
HTTPS 连接由客户端向 HTTP 服务器发送请求并要求启动安全 TLS 连接来发起。 在此过程中:
客户端验证服务器证书的签名并执行任何其他操作