Google cloud platform 条带错误:未找到与负载的预期签名匹配的签名
我有一个调用Firebase函数的条带webhook。在这个函数中,我需要验证这个请求是否来自条带服务器。代码如下:Google cloud platform 条带错误:未找到与负载的预期签名匹配的签名,google-cloud-platform,google-cloud-functions,stripe-payments,Google Cloud Platform,Google Cloud Functions,Stripe Payments,我有一个调用Firebase函数的条带webhook。在这个函数中,我需要验证这个请求是否来自条带服务器。代码如下: const functions = require('firebase-functions'); const bodyParser = require('body-parser'); const stripe = require("stripe")("sk_test_****"); const endpointSecret = 'whsec_****'; const app =
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);
如中所述,我必须使用原始主体来执行此安全检查
我已尝试使用我的当前代码和:
app.use(require('body-parser').raw({type: '*/*'}));
但我总是犯这样的错误:
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
云自动运行。如果您得到的是JSON,那么它已经被解析并在
req.body
中提供给您。您不需要添加其他主体解析中间件
如果您需要处理原始数据,您应该使用
req.rawBody
,但我认为您不需要在这里这样做。以下是适用于我的代码:
app.use(bodyParser.json({
验证:功能(req、res、buf){
var url=req.originalUrl;
if(url.startsWith('/stripe')){
req.rawBody=buf.toString();
}
}
}));
然后通过req.rawBody进行验证
stripe.checkWebHook(要求原始体,签名);
参考资料:在我重命名firebase cloud函数后,从Stripe仪表板发送测试webhook时发生了这种情况。我所有的其他功能都正常工作。通过在终端中重新设置解决 firebase函数:config:set stripe.webhook\u signature=“您的webhook签名秘密” (如果您正在使用)并重新部署功能firebase deploy——仅限功能
第二次,我通过在stripe dashboard中滚动条带签名来解决问题。我能够从一个webhook获得数据,但无法从第二个webhook获得数据:问题是我使用的密钥与第一个webhook使用的密钥相同,但我发现每个webhook都有不同的密钥,这就是我得到同样信息的方式。以下是对我有效的方法: 添加此行:
app.use('/api/subs/stripe-webhook', bodyParser.raw({type: "*/*"}))
app.use(bodyParser.json());
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 });
}
就在这行前面:
app.use('/api/subs/stripe-webhook', bodyParser.raw({type: "*/*"}))
app.use(bodyParser.json());
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 });
}
(它不会影响您的所有操作,只是:'/api/subs/stripewebhook')
然后:
app.use('/api/subs/stripe-webhook', bodyParser.raw({type: "*/*"}))
app.use(bodyParser.json());
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 });
}
2021年-解决方案
我面临着这个错误,经过大量的研究,我无法轻松地解决这个问题,但最终我可以在我的架构中实现这一点,如下所示:
//App.js
this.server.use((req, res, next) => {
if (req.originalUrl.startsWith('/webhook')) {
next();
} else {
express.json()(req, res, next);
}
});
需要注意的两大警告:
app.use('/api/subs/stripe-webhook', bodyParser.raw({type: "*/*"}))
app.use(bodyParser.json());
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 });
}
- 确保发送
req.headers['stripe-signature']
- 确保您的
是正确的,否则它仍会显示相同的错误endpointSecret
app.use('/api/subs/stripe-webhook', bodyParser.raw({type: "*/*"}))
app.use(bodyParser.json());
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 });
}
- 通过安装Stripe CLI进行本地测试:
- 在stripe dashboard上验证您的密钥,或者您也可以通过验证您的stripe日志来确保您的密钥是否正确,如下所示:
//对所有非webhook路由使用JSON解析器
应用程序使用(
bodyParser.json({
验证:(req、res、buf)=>{
const url=req.originalUrl;
if(url.startsWith('/api/stripe/webhook')){
req.rawBody=buf.toString();
}
}
})
);
对于上述答案,上面的代码看起来很好。但即使是我也犯了一个错误。放了同样的东西后,我也犯了同样的错误
最后,我发现如果在rawBody
代码下面配置body解析器,那么它就可以工作了
像这样
//对所有非webhook路由使用JSON解析器
应用程序使用(
bodyParser.json({
验证:(req、res、buf)=>{
const url=req.originalUrl;
if(url.startsWith('/api/stripe/webhook')){
req.rawBody=buf.toString();
}
}
})
);
//设置快速响应和正文解析器配置
使用(express.json());
use(bodyParser.json());
use(bodyParser.urlencoded({extended:true}));
希望它能帮助某人。请使用此脚本
app.use(
bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf;
},
})
);
我只需要在
constructEvent()
中使用req.rawBody
。愚蠢的错误,谢谢。面对Java中的相同问题,有任何建议,请获取req.rawBody
定义,我必须执行app.use(express.json({verify:{req,res,buf)=>{req.rawBody=buf})使用(express.json())代码>。或者,我想我可以在app.use(express.json())
之前访问req.body
,但是这样我可以在任何地方访问原始body。对不起,req.rawBody很好。我错把箭放下了。现在我的投票被锁定了,我不能切换到向上箭头。@pref这很奇怪。你应该可以在任何时候改变你的投票。这比或好多少?