Node.js中为HubSpot与Stripe API适配express.raw的问题咨询
我正在搭建一款运行于平台的应用,需接收应用的webhook并调用API执行操作。多数功能使用HubSpot API实现,支付及支付状态验证使用Stripe API,整体基于Node.js的Express框架开发,用于监听端点并处理请求。
当前Express配置如下:
const express = require('express') const app = express() app.use(express.raw({type: "application/json"})) app.use(express.json())
使用express.raw是因为Stripe API需要将原始请求转换为Buffer。但这导致非Stripe接口(如获取HubSpot账户设置的/account-fetch端点)出现问题:req.body变为编码后的Buffer,仅输出数字,无法正常读取参数。
我尝试仅在Stripe端点单独配置express.raw:
app.post('/stripe/:type', express.raw({type: "application/json"}),(req, res) => { //rest of my code })
或完全不配置该中间件,但均无效,仍出现StripeSignatureVerificationError,无法正确验证负载签名。也曾尝试将该配置放在Stripe端点前,同样失败。
请问是否可将Buffer转回未使用express.raw时的格式,或仅为单个端点隔离使用express.raw?
方案1:为单个Stripe端点单独配置express.raw并正确验证签名
你之前的代码存在语法错误("application/json缺少闭合引号),修正后通过调整中间件顺序,就能实现仅Stripe端点使用raw解析:
// 先全局配置JSON解析,供非Stripe路由使用 app.use(express.json()); // 单独给Stripe路由挂载raw解析中间件,确保参数完整 app.post('/stripe/:type', express.raw({ type: 'application/json' }), (req, res) => { const sig = req.headers['stripe-signature']; const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; try { // 直接用req.body(Buffer格式)进行Stripe签名验证 const event = stripe.webhooks.constructEvent( req.body, sig, webhookSecret ); // 处理Stripe事件的业务逻辑 res.json({ received: true }); } catch (err) { res.status(400).send(`Webhook Error: ${err.message}`); return; } }); // 非Stripe路由示例:HubSpot账户设置获取 app.get('/account-fetch', (req, res) => { // 此处req.body已自动解析为JSON格式,可直接读取参数 res.json({ settings: /* 你的业务逻辑结果 */ }); });
核心逻辑是Express中间件按注册顺序执行,Stripe路由优先使用自身挂载的express.raw,其他路由则使用全局的express.json解析,互不干扰。
方案2:将Buffer手动转回JSON格式(适配全局raw解析场景)
如果必须全局使用express.raw,可以在非Stripe路由中手动将Buffer转换为JSON:
app.get('/account-fetch', (req, res) => { let requestBody; try { // 将Buffer转为UTF-8字符串后解析为JSON requestBody = JSON.parse(req.body.toString('utf8')); } catch (error) { return res.status(400).send('Invalid JSON payload'); } // 现在可以正常使用requestBody中的参数 res.json({ settings: requestBody.accountId }); });
这种方式需要在每个非Stripe路由中重复转换逻辑,不如方案1优雅,仅作为特殊场景的备选方案。
关键注意事项
- 确保Stripe后台配置的webhook签名密钥与代码中
webhookSecret完全一致 - 不要在Stripe路由之前挂载任何会修改请求体的中间件(比如
express.json()),否则原始Buffer会被破坏,导致签名验证失败 - 检查请求头中是否存在
stripe-signature字段,缺失会直接触发StripeSignatureVerificationError
内容的提问来源于stack exchange,提问作者Jknight

