Pau*_*uli 1 ruby ruby-on-rails webhooks stripe-payments
我目前正在处理我的 Webhooks,但我的 Webhooks 控制器中出现错误。
这是错误:
#<Stripe::SignatureVerificationError: No signatures found matching the expected signature for payload>
No template found for WebhooksController#create, rendering head :no_content
Completed 204 No Content in 1ms (Allocations: 594)
Run Code Online (Sandbox Code Playgroud)
经过一段时间尝试调试这个问题后,我发现它来自这些行,因为我在控制台中看到的最后一个代码是错误和“签名错误”...
rescue Stripe::SignatureVerificationError => e
# Invalid signature
puts "Signature error"
p e
return
end
Run Code Online (Sandbox Code Playgroud)
这是控制器:
class WebhooksController < ApplicationController
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
def create
payload = request.body.read
sig_header = request.env['HTTP_STRIPE_SIGNATURE']
event = nil
begin
event = Stripe::Webhook.construct_event(
payload, sig_header, Rails.application.credentials[:stripe][:webhook]
)
rescue JSON::ParserError => e
status 400
# Invalid payload
puts "Payload error"
return
rescue Stripe::SignatureVerificationError => e
# Invalid signature
puts "Signature error"
p e
return
end
# Handle the event
case event.type
when 'checkout.session.completed'
booking = Booking.find_by(checkout_session_id: event.data.object.id)
booking.update(paid: true)
booking.save
# @booking = Booking.where(checkout_session_id: event.data.object.id)
# @booking.update(paid: true)
# @booking.save
end
render json: { message: 'success' }
end
end
Run Code Online (Sandbox Code Playgroud)
任何帮助都会很棒,因为我已经为此苦苦挣扎了一段时间。
验证 Webhook 签名通常会因 2 个具体原因而失败:
第一个相当容易调试,但它却困扰了很多开发人员。当您创建 WebhookEndpoint(在 API 或仪表板中)时,您会得到一个secret看起来像whsec_12334ABC.... 您需要确保您的代码使用该确切的秘密才能验证签名。请注意,如果您使用 Stripe CLI 来测试此流程,它会为您提供一个不同的秘密,在这种情况下您必须使用该特定秘密。
如果您确信自己使用的是正确的秘密,那么第二个常见的根本原因是有效负载的内容。当 Stripe 生成签名时,它会在特定版本的有效负载上以 JSON 形式进行签名。为了验证签名,您必须使用完全相同的有效负载。
问题在于,许多 Web 框架(例如 Express for Node.js 或 Rails for Ruby)都会篡改原始有效负载。当它收到请求时,它会看到 JSON,因此它会尝试为您提供帮助并解析数据。然后,当您请求内容时,它不会向您提供原始内容/有效负载,而是将 JSON 重新序列化为字符串。这样做通常会更改原始有效负载,例如删除/添加空格/缩进或更改属性本身的顺序。如果有效负载与 Stripe 发送给您的内容不同,则签名无法匹配,因此会出错。
使用 Rails,您可能想要尝试request.raw_post或找到类似的解决方案来获取发送给您的确切原始 JSON。
| 归档时间: |
|
| 查看次数: |
1251 次 |
| 最近记录: |