Ker*_*mit 8 javascript parsing express stripe-payments
我正在尝试在我的 Web API 中实现 Stripe,并且需要读取请求的原始正文。我的应用程序中已经有不需要原始主体的现有 API 路径。
\n我实现的代码基于 Stripe 文档示例,请参见下文。
\nconst stripe = require('stripe')('apikey...');\nconst endpointSecret = 'whsec_...';\n\nconst express = require('express');\nconst app = express();\napp.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {\n let event = request.body;\n console.log('body', event);\n const headers = JSON.stringify(request.headers);\n console.log('Headers', headers);\n // Only verify the event if you have an endpoint secret defined.\n // Otherwise use the basic event deserialized with JSON.parse\n if (endpointSecret) {\n // Get the signature sent by Stripe\n const signature = request.headers['stripe-signature'];\n try {\n event = stripe.webhooks.constructEvent(request.body, signature, endpointSecret);\n } catch (err) {\n console.log(`\xe2\x9a\xa0\xef\xb8\x8f Webhook signature verification failed.`, err.message);\n return response.sendStatus(400);\n }\n }\n\n // Handle the event\n ...\n // Return a 200 response to acknowledge receipt of the event\n response.send();\n});\n\napp.listen(443, () => console.log('Running on port 443'));\nRun Code Online (Sandbox Code Playgroud)\n此代码记录以下消息 - 因为原始主体是空的。
\nbody\nHeaders {"host":".....}\n\xe2\x9a\xa0\xef\xb8\x8f Webhook signature verification failed. No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing\nRun Code Online (Sandbox Code Playgroud)\n我尝试通过添加中间件来读取原始主体来解决此问题。
\n// Custom middleware that keeps the raw request body. This is needed for Stripe\napp.use((req, res, next)=>{\n req.rawBody = '';\n req.on('data', (chunk) => { req.rawBody += chunk; });\n req.on('end', () => {\n try {\n req.body = JSON.parse(req.rawBody);\n next();\n } catch (err) {\n console.log('Error parsing body')\n next();\n }\n });\n });\n\napp.post('/webhook', (request, response) => {\n let event = request.body;\n console.log('rawBody', request.rawBody)\n if (endpointSecret) {\n // Get the signature sent by Stripe\n const signature = request.headers['stripe-signature'];\n try {\n event = stripe.webhooks.constructEvent(request.rawBody, signature, endpointSecret);\n } catch (err) {\n console.log(`\xe2\x9a\xa0\xef\xb8\x8f Webhook signature verification failed.`, err.message);\n return resp.sendStatus(400);\n }\nRun Code Online (Sandbox Code Playgroud)\n根据记录,原始尸体仍然是空的。我仍然在控制台中收到相同的错误消息。
\n如何将原始正文添加到请求中?最好使用中间件。\n亲切的问候 /K
\n更新:(感谢 Bravo!)\n下面的代码似乎可以通过暴露原始主体来工作
\napp.post('/webhook', express.raw(), (request, response) => {\n let event = request.rawBody;\nRun Code Online (Sandbox Code Playgroud)\n
我能够通过将该verify方法添加到中间件配置(在幕后express.json使用)来解决这个问题。body-parser
例子:
const RAW_BODY_WHITELIST = ['/webhooks/stripe'];
app.use(express.json({
verify: (req: Request, _res: Response, buf: Buffer, _encoding: string) => {
if (RAW_BODY_WHITELIST.includes(req.path)) {
req.rawBody = buf.toString();
}
},
}));
Run Code Online (Sandbox Code Playgroud)
这样,您就可以很好地组织所有中间件,并且不必在其他中间件之前或之间声明 Webhook 路由。