Webhook 签名验证失败,带有快速条带
Webhook signature verification failed with express stripe
我正在尝试在本地测试 webhook 条纹事件,但它说:
Webhook 签名验证失败。
所以这是我的 webhook 端点:
exports.stripeListenWebhook = (req, res) => {
let data
let eventType
const webhookSecret = 'whsec_VjORamXpVZs1j6mCV0eTyE7B2GI92'
if (webhookSecret) {
// Retrieve the event by verifying the signature using the raw body and secret.
let event
let signature = req.headers['stripe-signature']
console.log(req.headers)
try {
event = stripe.webhooks.constructEvent(req.body, signature, webhookSecret)
} catch (err) {
console.log(`⚠️ Webhook signature verification failed.`)
return res.sendStatus(400)
}
// Extract the object from the event.
data = event.data
eventType = event.type
} else {
// Webhook signing is recommended, but if the secret is not configured in `config.js`,
// retrieve the event data directly from the request body.
data = req.body.data
eventType = req.body.type
}
// Handle the event
switch (eventType) {
case 'checkout.session.completed':
const session = data.object
console.log(session)
// Then define and call a function to handle the event checkout.session.completed
break
default:
console.log(`Unhandled event type ${eventType}`)
}
res.json({ received: true })
}
我的console.log(req.headers)
执行此命令后的输出:
条纹触发器checkout.session.completed
{
host: 'localhost:8000',
'user-agent': 'Stripe/1.0 (+https://stripe.com/docs/webhooks)',
'content-length': '1923',
accept: '*/*; q=0.5, application/xml',
'cache-control': 'no-cache',
'content-type': 'application/json; charset=utf-8',
'stripe-signature': 't=1638211722,v1=08ed8a55af610fdb97d928c4ec068d19badfb82fe0a521aee7d8f8cfbe378d63,v0=aeebf964e3da2a19f9a533743d420804c168395bb25bf4789e04cfcd9f573d52',
'accept-encoding': 'gzip'
}
我遵循文档中的规则,并且在我的 app.js 中使用此配置:
const corsOptions = {
origin: [URLConfig.URL_CLIENT],
credentials: true,
methods: 'POST, PUT, OPTIONS, DELETE, GET, PATCH',
allowedHeaders: 'Origin, X-Requested-With, Content, Accept, Content-Type, Authorization',
}
app.use(cors(corsOptions))
app.use(cookieParser())
app.use(express.json())
app.use(
express.urlencoded({
extended: true,
})
)
有人对我的问题有意见吗?我看到 body-parser 被贬低了,所以我用 express.json() 代替
我用express.raw({ type: 'application/json' }) 替换它,基本上如果express.json() 放在它前面是行不通的:
app.use(express.json())
app.use(
express.urlencoded({
extended: true,
})
)
app.use(URLConfig.URL_API + '/webhooks-stripe', express.raw({ type: 'application/json' }), WebHooksRoutes) / this need to be placed before
所以解决方案是:
app.use(URLConfig.URL_API + '/webhooks-stripe', express.raw({ type: 'application/json' }), WebHooksRoutes)
app.use(express.json())
app.use(
express.urlencoded({
extended: true,
})
)
更改为更通用的解决方案:
const rawBodyBuffer = (
req: http.IncomingMessage,
res: http.ServerResponse,
buffer: Buffer,
encoding: BufferEncoding,
) => {
if (!req.headers['stripe-signature']) {
return;
}
if (buffer && buffer.length) {
req['rawBody'] = buffer.toString(encoding || 'utf8');
}
};
app.use(urlencoded({ verify: rawBodyBuffer, extended: true }));
我正在尝试在本地测试 webhook 条纹事件,但它说:
Webhook 签名验证失败。
所以这是我的 webhook 端点:
exports.stripeListenWebhook = (req, res) => {
let data
let eventType
const webhookSecret = 'whsec_VjORamXpVZs1j6mCV0eTyE7B2GI92'
if (webhookSecret) {
// Retrieve the event by verifying the signature using the raw body and secret.
let event
let signature = req.headers['stripe-signature']
console.log(req.headers)
try {
event = stripe.webhooks.constructEvent(req.body, signature, webhookSecret)
} catch (err) {
console.log(`⚠️ Webhook signature verification failed.`)
return res.sendStatus(400)
}
// Extract the object from the event.
data = event.data
eventType = event.type
} else {
// Webhook signing is recommended, but if the secret is not configured in `config.js`,
// retrieve the event data directly from the request body.
data = req.body.data
eventType = req.body.type
}
// Handle the event
switch (eventType) {
case 'checkout.session.completed':
const session = data.object
console.log(session)
// Then define and call a function to handle the event checkout.session.completed
break
default:
console.log(`Unhandled event type ${eventType}`)
}
res.json({ received: true })
}
我的console.log(req.headers)
执行此命令后的输出:
条纹触发器checkout.session.completed
{
host: 'localhost:8000',
'user-agent': 'Stripe/1.0 (+https://stripe.com/docs/webhooks)',
'content-length': '1923',
accept: '*/*; q=0.5, application/xml',
'cache-control': 'no-cache',
'content-type': 'application/json; charset=utf-8',
'stripe-signature': 't=1638211722,v1=08ed8a55af610fdb97d928c4ec068d19badfb82fe0a521aee7d8f8cfbe378d63,v0=aeebf964e3da2a19f9a533743d420804c168395bb25bf4789e04cfcd9f573d52',
'accept-encoding': 'gzip'
}
我遵循文档中的规则,并且在我的 app.js 中使用此配置:
const corsOptions = {
origin: [URLConfig.URL_CLIENT],
credentials: true,
methods: 'POST, PUT, OPTIONS, DELETE, GET, PATCH',
allowedHeaders: 'Origin, X-Requested-With, Content, Accept, Content-Type, Authorization',
}
app.use(cors(corsOptions))
app.use(cookieParser())
app.use(express.json())
app.use(
express.urlencoded({
extended: true,
})
)
有人对我的问题有意见吗?我看到 body-parser 被贬低了,所以我用 express.json() 代替
我用express.raw({ type: 'application/json' }) 替换它,基本上如果express.json() 放在它前面是行不通的:
app.use(express.json())
app.use(
express.urlencoded({
extended: true,
})
)
app.use(URLConfig.URL_API + '/webhooks-stripe', express.raw({ type: 'application/json' }), WebHooksRoutes) / this need to be placed before
所以解决方案是:
app.use(URLConfig.URL_API + '/webhooks-stripe', express.raw({ type: 'application/json' }), WebHooksRoutes)
app.use(express.json())
app.use(
express.urlencoded({
extended: true,
})
)
更改为更通用的解决方案:
const rawBodyBuffer = (
req: http.IncomingMessage,
res: http.ServerResponse,
buffer: Buffer,
encoding: BufferEncoding,
) => {
if (!req.headers['stripe-signature']) {
return;
}
if (buffer && buffer.length) {
req['rawBody'] = buffer.toString(encoding || 'utf8');
}
};
app.use(urlencoded({ verify: rawBodyBuffer, extended: true }));