Xero - 接收意图 Ruby
Xero - Intent To Receive Ruby
这是来自 Xero 的参数
{"events"=>nil,
"firstEventSequence"=>0,
"lastEventSequence"=>0,
"entropy"=>"KFDXIMNLPDAMRBOEVAVF",
"controller"=>"admin/billing/webhooks",
"action"=>"handle_hook",
"webhook"=>
{"events"=>nil,
"firstEventSequence"=>0,
"lastEventSequence"=>0,
"entropy"=>"KFDXIMNLPDAMRBOEVAVF"}}
我要验证Intent To Receive
https://developer.xero.com/documentation/webhooks/configuring-your-server#intent
data = {"events"=>nil, "firstEventSequence"=>0, "lastEventSequence"=>0, "entropy"=>"KFDXIMNLPDAMRBOEVAVF"}
Key = HRj6QPub9BNE4MWewrcLrkKFjpiikV1KrlMZCvDawyDR95MGkkuE2y1DXFP1tifsEWaJygLx6zG0r9rXVTflcg==
试过以下
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), key, data)).strip()
*** TypeError Exception: no implicit conversion of ActionController::Parameters into String
或
hash = OpenSSL::HMAC.digest('sha256', key, data)
*** TypeError Exception: no implicit conversion of ActionController::Parameters into String
这里如何实现?
为确保您收到的请求来自 Xero,您需要验证 x-xero-signature header 中提供的签名。创建或 re-enabling webhook 订阅(或更新订阅 url)时,系统将提示用户开始 'Intent To Receive' 验证。此验证过程将是对订阅中提供的 url 的一系列 HTTPS POST 请求。
编辑
Rails 正在将空白数组转换为 nil,所以我根据文档自己制作了 payload,看起来完全一样
data = params[:webhook]
payload = {
"events": [],
"lastEventSequence": data[:lastEventSequence],
"firstEventSequence": data[:firstEventSequence],
"entropy": data[:entropy]
}
data
应该是一个字符串。
digest = OpenSSL::Digest::Digest.new('sha256')
hmac_digest = OpenSSL::HMAC.digest(digest, key, data['firstEventSequence'].to_s)
Base64.encode64(hmac_digest).strip() => "JvORQ/sWHvAXO/3nm9vG7+VgAqA93bTSMMIbVHIRgnM="
经过研究和调试代码终于找到了方法来做到这一点
def handle_hook
key = ENV['XERO_WEBHOOK_KEY']
payload = request.body.read
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest('sha256', key, payload))
if calculated_hmac.strip() == request.headers['x-xero-signature']
head :ok
else
head :unauthorized
end
end
在这里使用 Strip() 很神奇
这是来自 Xero 的参数
{"events"=>nil,
"firstEventSequence"=>0,
"lastEventSequence"=>0,
"entropy"=>"KFDXIMNLPDAMRBOEVAVF",
"controller"=>"admin/billing/webhooks",
"action"=>"handle_hook",
"webhook"=>
{"events"=>nil,
"firstEventSequence"=>0,
"lastEventSequence"=>0,
"entropy"=>"KFDXIMNLPDAMRBOEVAVF"}}
我要验证Intent To Receive
https://developer.xero.com/documentation/webhooks/configuring-your-server#intent
data = {"events"=>nil, "firstEventSequence"=>0, "lastEventSequence"=>0, "entropy"=>"KFDXIMNLPDAMRBOEVAVF"}
Key = HRj6QPub9BNE4MWewrcLrkKFjpiikV1KrlMZCvDawyDR95MGkkuE2y1DXFP1tifsEWaJygLx6zG0r9rXVTflcg==
试过以下
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), key, data)).strip()
*** TypeError Exception: no implicit conversion of ActionController::Parameters into String
或
hash = OpenSSL::HMAC.digest('sha256', key, data)
*** TypeError Exception: no implicit conversion of ActionController::Parameters into String
这里如何实现?
为确保您收到的请求来自 Xero,您需要验证 x-xero-signature header 中提供的签名。创建或 re-enabling webhook 订阅(或更新订阅 url)时,系统将提示用户开始 'Intent To Receive' 验证。此验证过程将是对订阅中提供的 url 的一系列 HTTPS POST 请求。
编辑 Rails 正在将空白数组转换为 nil,所以我根据文档自己制作了 payload,看起来完全一样
data = params[:webhook]
payload = {
"events": [],
"lastEventSequence": data[:lastEventSequence],
"firstEventSequence": data[:firstEventSequence],
"entropy": data[:entropy]
}
data
应该是一个字符串。
digest = OpenSSL::Digest::Digest.new('sha256')
hmac_digest = OpenSSL::HMAC.digest(digest, key, data['firstEventSequence'].to_s)
Base64.encode64(hmac_digest).strip() => "JvORQ/sWHvAXO/3nm9vG7+VgAqA93bTSMMIbVHIRgnM="
经过研究和调试代码终于找到了方法来做到这一点
def handle_hook
key = ENV['XERO_WEBHOOK_KEY']
payload = request.body.read
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest('sha256', key, payload))
if calculated_hmac.strip() == request.headers['x-xero-signature']
head :ok
else
head :unauthorized
end
end
在这里使用 Strip() 很神奇