当我试图验证Stripe Webhook的签名时,存在某种编码问题。我知道这不是Stripe包本身的问题,因为当我试图手动对主体数据进行哈希处理,并将HMAC-256SHA签名与Stripe在头文件中的签名进行比较时,我得到了不同的签名。我已经尝试了很多不同的东西到很多不同的部分,所以有可能我有多个错误。
你在这里看不出来,但是IBM云功能已经被设置为传递原始的HTTP数据,这就是为什么你这个解码功能被使用。
在没有验证签名的情况下,webhook是成功的。
Stripe事件函数产生的错误是:"没有找到与预期的payload签名相匹配的签名"。你是否传递了从Stripe收到的原始请求体?"
注意:在尝试调试这个问题时,这里没有正确处理错误。
const stripe = require('stripe')('sk_test_********’);
var crypto = require('crypto');
// tried with the CLI secret and the one from the dashboard.
const endpointSecret = 'whsec_****’;
// Convert the stripe signature in string format to a JSON object
function sig_conversion(data){
var sig_obj = {}
var data_list = data.split(",").map((x)=>x.split("="));
var data_json = data_list.map((x)=>{sig_obj[x[0]] = x[1]})
return sig_obj
}
function decode(args) {
var decoded = new Buffer.from(args.__ow_body, 'base64')//.toString('utf-8')
return {body: decoded}
}
function main(params){
//let sig = sig_conversion(params.__ow_headers['stripe-signature']);
let sig = params.__ow_headers['stripe-signature']
let signature = sig_conversion(params.__ow_headers['stripe-signature']);
//console.log(222, signature);
var data = decode(params);
let event;
// Trying to see the result from manually checking the signatures.
var signed_payload = data.body + "." + signature.t
var hmac = crypto.createHmac('sha256', endpointSecret);
var hmac_sig = hmac.update(signed_payload);
var gen_hmac= hmac_sig.digest('hex');
console.log(gen_hmac, 222, signature, 444)
try {
event = stripe.webhooks.constructEvent(JSON.parse(data.body), sig, endpointSecret);
//event = JSON.parse(data.body);
}
这里有一些步骤可以帮助人们尝试同样的事情(其中一些步骤是一般步骤,与上面的问题没有直接关系)。
注意:使用Google Cloud Functions或Pub-sub的人很可能会遇到类似的签名验证问题。
function decode(args) {
var decoded = new Buffer.from(args.__ow_body, 'base64')
return {body: decoded}
}
// Match the raw body to content type application/json
function main(params){
let sig = params.__ow_headers['stripe-signature']
var data = decode(params);
let event;
try {
event = stripe.webhooks.constructEvent(data.body, sig, endpointSecret);
}
// The rest is the same as the stripe boilerplate code.
catch (err) {
return {
body: {payload:''},
statusCode:200,
headers:{ 'Content-Type': 'application/json'}
};
}
// Handle the event
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log('PaymentIntent was successful!')
break;
case 'payment_method.attached':
const paymentMethod = event.data.object;
console.log('PaymentMethod was attached to a Customer!')
break;
// ... handle other event types
default:
// Unexpected event type
return {
body: {payload:''},
statusCode:200,
headers:{ 'Content-Type': 'application/json'}
};
}
// Return a response to acknowledge receipt of the event
return {
body: {payload:''},
statusCode:200,
headers:{ 'Content-Type': 'application/json'}
};
};