Zat*_*t42 7 stripe-payments google-cloud-platform google-cloud-functions
我有一个条纹Webhook,它调用Firebase函数。在此功能中,我需要验证此请求是否来自Stripe服务器。这是代码:
const functions = require('firebase-functions');
const bodyParser = require('body-parser');
const stripe = require("stripe")("sk_test_****");
const endpointSecret = 'whsec_****';
const app = require('express')();
app.use(bodyParser.json({
verify: function (req, res, buf) {
var url = req.originalUrl;
if (url.startsWith('/webhook')) {
req.rawBody = buf.toString()
}
}
}));
app.post('/webhook/example', (req, res) => {
let sig = req.headers["stripe-signature"];
try {
console.log(req.bodyRaw)
let event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
console.log(event);
res.status(200).end()
// Do something with event
}
catch (err) {
console.log(err);
res.status(400).end()
}
});
exports.app = functions.https.onRequest(app);
Run Code Online (Sandbox Code Playgroud)
如Stripe文档中所述,我必须使用原始主体来执行此安全检查。
我已经尝试使用当前代码和:
app.use(require('body-parser').raw({type: '*/*'}));
Run Code Online (Sandbox Code Playgroud)
但是我总是会收到这个错误:
Error: 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
Run Code Online (Sandbox Code Playgroud)
Jer*_*yal 59
有2点需要注意:
如果使用 Firebase 云功能:
通过req.rawBody而不是req.body到constructEvent
const event = stripe.webhooks.constructEvent(
req.rawBody,
sig,
STRIPE_WEBHOOK_SECRET
);
Run Code Online (Sandbox Code Playgroud)
如果使用Next.jsVercel 函数:
export const config = {
api: {
bodyParser: false,
},
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const sig = req.headers["stripe-signature"]!;
const body = await buffer(req);
const event = stripeObj.webhooks.constructEvent(body, sig, key);
console.log("webhook verified");
switch (event.type) {
case "checkout.session.completed":
default:
console.error(`Unhandled event type ${event.type}`);
}
return res.status(200).json({});
}
const buffer = (req: NextApiRequest) => {
return new Promise<Buffer>((resolve, reject) => {
const chunks: Buffer[] = [];
req.on("data", (chunk: Buffer) => {
chunks.push(chunk);
});
req.on("end", () => {
resolve(Buffer.concat(chunks));
});
req.on("error", reject);
});
};
Run Code Online (Sandbox Code Playgroud)
检查其他服务器:https://github.com/stripe/stripe-node/tree/master/examples/webhook-signing
小智 17
这是对我有用的代码:
app.use(bodyParser.json({
verify: function (req, res, buf) {
var url = req.originalUrl;
if (url.startsWith('/stripe')) {
req.rawBody = buf.toString();
}
}
}));
Run Code Online (Sandbox Code Playgroud)
然后通过 req.rawBody 进行验证
stripe.checkWebHook(req.rawBody, signature);
Run Code Online (Sandbox Code Playgroud)
参考:https : //github.com/stripe/stripe-node/issues/341
Fáb*_*uza 17
2021 - 解决方案
我遇到了这个错误,经过大量研究后,我无法轻松找出问题,但最终我可以根据下面的架构来做到这一点:
//App.js
this.server.use((req, res, next) => {
if (req.originalUrl.startsWith('/webhook')) {
next();
} else {
express.json()(req, res, next);
}
});
Run Code Online (Sandbox Code Playgroud)
//routes.js
routes.post(
'/webhook-payment-intent-update',
bodyParser.raw({ type: 'application/json' }),
//your stripe logic (Im using a controller, but wherever)
(req, res) => {
stripe.webhooks.constructEvent(...)
}
)
Run Code Online (Sandbox Code Playgroud)
需要注意的两大警告:
req.headers['stripe-signature']endpointSecret正确,否则仍然会报同样的错误尖端:
通过安装 Stripe CLI 在本地进行测试:https ://stripe.com/docs/webhooks/test
在 Stripe 仪表板上验证您的密钥,或者您也可以通过验证您的 Stripe 日志来确保您是否拥有正确的密钥,如下所示:
我希望它对你有帮助。:)
Mat*_*asG 11
这是对我有用的:
添加这一行:
app.use('/api/subs/stripe-webhook', bodyParser.raw({type: "*/*"}))
Run Code Online (Sandbox Code Playgroud)
(第一个参数指定我们应该在哪个路由上使用原始正文解析器。请参阅app.use()参考文档。)
就在这一行之前:
app.use(bodyParser.json());
Run Code Online (Sandbox Code Playgroud)
(它不会影响你的所有操作,只是这个:'/api/subs/stripe-webhook')
注意:如果你使用 Express 4.16+ 你可以用 express 替换 bodyParser:
app.use('/api/subs/stripe-webhook', express.raw({type: "*/*"}));
app.use(express.json());
Run Code Online (Sandbox Code Playgroud)
然后:
const endpointSecret = 'whsec_........'
const stripeWebhook = async (req, res) => {
const sig = req.headers['stripe-signature'];
let eventSecure = {}
try {
eventSecure = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
//console.log('eventSecure :', eventSecure);
}
catch (err) {
console.log('err.message :', err.message);
res.status(400).send(`Webhook Secure Error: ${err.message}`)
return
}
res.status(200).send({ received: true });
}
Run Code Online (Sandbox Code Playgroud)
Cloud Functions自动解析已知类型的正文内容。如果您要获取JSON,那么它已经被解析并且可以在中使用req.body。您不需要添加其他主体解析中间件。
如果您需要处理原始数据,则应使用req.rawBody,但我认为您无需在此处进行处理。
| 归档时间: |
|
| 查看次数: |
2002 次 |
| 最近记录: |