我有一个调用Firebase函数的条纹Webhook。在此功能中,我需要验证此请求是否来自Stripe服务器。这是代码:
-module(collatzMaps).
-export([start/2, s/4]).
collatz(0, Map) ->
{0, Map};
collatz(M, Map) ->
Exists = maps:is_key(M, Map),
case Exists of
false ->
case M rem 2 == 0 of
true ->
Result = collatz(M div 2, Map),
Val = (1 + element(1, Result)),
Map1 = maps:put(M, Val, element(2, Result)),
{maps:get(M, Map1), Map1};
false ->
Result = collatz((3 * M + 1), Map),
Val = (1 + element(1, Result)),
Map2 = maps:put(M, Val, element(2, Result)),
{maps:get(M, Map2), Map2}
end;
true ->
{maps:get(M, Map), Map}
end.
s(N, M, Max, Map) ->
if
N =< M ->
Result = collatz(N, Map),
if
element(1, Result) > Max ->
NextMax = element(1, Result),
MapNext = element(2, Result),
s(N + 1, M, NextMax, MapNext);
true ->
MapNext = element(2, Result),
s(N + 1, M, Max, MapNext)
end;
true ->
Max
end.
start(N, M)->
statistics(runtime),
statistics(wall_clock),
Map = maps:new(),
Map1 = maps:put(1, 1, Map),
G = s(N, M, 0, Map1),
{_, Time2} = statistics(wall_clock),
U2 = Time2 / 1000,
io:format("~p seconds~n", [U2]),
G.
如Stripe Documentation中所述,我必须使用原始主体来执行此安全检查。
我尝试使用当前代码和:
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: '*/*'}));
答案 0 :(得分:5)
这是对我有用的东西
添加此行:
app.use('/api/subs/stripe-webhook', bodyParser.raw({type: "*/*"}))
在此行之前:
app.use(bodyParser.json());
(这不会影响您的所有操作,只是这样:'/ api / subs / stripe-webhook')
然后:
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 });
}
答案 1 :(得分:3)
云功能自动parses body content of known types。如果您要获取JSON,则说明它已经解析并且可以在req.body
中使用。您不需要添加其他主体解析中间件。
如果您需要处理原始数据,则应使用req.rawBody
,但我认为您不需要在此处进行处理。
答案 2 :(得分:2)
2021 - 解决方案
我遇到了那个错误,经过大量研究后,我无法轻松找出问题所在,但最终我可以根据以下架构来解决:
//App.js
this.server.use((req, res, next) => {
if (req.originalUrl.startsWith('/webhook')) {
next();
} else {
express.json()(req, res, next);
}
});
//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(...)
}
)
需要注意的两大警告:
req.headers['stripe-signature']
endpointSecret
是正确的,否则它仍然会报同样的错误提示:
通过安装 Stripe CLI 在本地进行测试:https://stripe.com/docs/webhooks/test
在条带控制面板上验证您的密钥,或者您也可以通过验证条带日志来确定您是否拥有正确的密钥,如下所示:
希望对你有帮助。 :)
答案 3 :(得分:1)
以下是对我有用的代码:
app.use(bodyParser.json({
verify: function (req, res, buf) {
var url = req.originalUrl;
if (url.startsWith('/stripe'))
req.rawBody = buf.toString();
}
}));
然后通过req.rawBody进行验证
stripe.checkWebHook(req.rawBody, signature);
答案 4 :(得分:1)
我能够从一个Webhook中获取数据,但不能从另一个Webhook中获取数据:问题是我使用的密钥与用于第一个Webhook的密钥相同,但是我发现每个Webhook都有不同的信息密钥,这就是我收到相同消息的方式。
答案 5 :(得分:0)
在我将Firebase云功能重命名后,从Stripe仪表板发送测试Webhook时,这发生了。我的所有其他功能都工作正常。通过在终端中重新设置解决 firebase函数:config:set stripe.webhook_signature =“您的Webhook签名机密” (如果您正在使用的话)并重新部署功能 firebase deploy --only功能
第二次,我通过在条纹仪表板中滚动条纹签名解决了该问题。
答案 6 :(得分:0)
// Use JSON parser for all non-webhook routes
app.use(
bodyParser.json({
verify: (req, res, buf) => {
const url = req.originalUrl;
if (url.startsWith('/api/stripe/webhook')) {
req.rawBody = buf.toString();
}
}
})
);
上面的代码对于上面的答案看起来很好。但即使是我也犯了一个错误。放同样的东西后,我得到了同样的错误。
最后,我发现如果您在 rawBody
代码下方配置了 body-parser,它就会起作用。
像这样
// Use JSON parser for all non-webhook routes
app.use(
bodyParser.json({
verify: (req, res, buf) => {
const url = req.originalUrl;
if (url.startsWith('/api/stripe/webhook')) {
req.rawBody = buf.toString();
}
}
})
);
// Setup express response and body parser configurations
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
希望对某人有所帮助。
答案 7 :(得分:0)
请使用此脚本
app.use(
bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf;
},
})
);