You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase集成Express时,Stripe Webhook使用express.raw失效问题

Firebase云函数中Express处理Stripe Webhook签名验证失败的原因及解决方法

问题背景

在Firebase云函数中用Express配置Stripe Webhook时,始终触发签名验证错误:

"Webhook Error: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?"

尝试了Express官方推荐的express.raw({type: 'application/json'})、条件跳过JSON解析等多种方案均无效,但改用Firebase原生onRequest方法直接读取req.rawBody后,验证立刻通过。核心疑问是Express方案失效的原因,以及如何让Express方案正常工作。

核心原因

Firebase云函数的HTTP触发器默认会提前自动解析请求体,导致Express中间件拿到的不是Stripe需要的原始请求字节数据。

Stripe的签名验证要求完全匹配请求的原始字节内容,但Firebase在把请求转发给Express应用之前,已经对请求体做了解析、编码转换等处理,Express拿到的req.body是经过Firebase处理后的版本,和Stripe发送的原始数据存在差异,因此无法通过签名验证。

而原生onRequest方法中,req.rawBody直接保留了Firebase接收到的原始请求字节,没有经过任何解析修改,所以能通过Stripe的签名校验。

解决Express方案的方法

要在Firebase上用Express正常处理Stripe Webhook,核心是绕过Firebase的自动解析,确保拿到原始请求体。

方法1:禁用云函数的自动请求体解析

导出云函数时配置rawBody: true,让Express直接处理原始请求:

const express = require('express');
const app = express();
const stripe = require('stripe')(functions.config().stripe.secret_key);

// Webhook路由直接使用raw中间件处理原始请求
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const webhookSecret = functions.config().stripe.webhook_secret_key;
  let event;

  try {
    event = stripe.webhooks.constructEvent(
      req.body,
      req.headers['stripe-signature'],
      webhookSecret
    );
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // 编写你的Webhook事件处理逻辑
  // ...

  res.json({ received: true });
});

// 导出云函数时禁用自动解析,保留原始请求体
exports.stripeApi = functions.https.onRequest({ rawBody: true }, app);

方法2:直接从Firebase请求对象获取原始体

如果无法全局禁用自动解析,可在Express中间件里直接读取Firebase附加的rawBody字段:

const express = require('express');
const app = express();
const stripe = require('stripe')(functions.config().stripe.secret_key);

// 不需要额外的raw中间件,直接用Firebase提供的rawBody
app.post('/webhook', (req, res) => {
  const webhookSecret = functions.config().stripe.webhook_secret_key;
  let event;

  try {
    event = stripe.webhooks.constructEvent(
      req.rawBody.toString(),
      req.headers['stripe-signature'],
      webhookSecret
    );
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // 编写你的Webhook事件处理逻辑
  // ...

  res.json({ received: true });
});

exports.stripeApi = functions.https.onRequest(app);

总结

Firebase云函数默认的请求体解析行为是Express方案失效的关键,它破坏了Stripe签名验证所需的原始请求数据一致性。通过禁用自动解析或直接读取req.rawBody,就能在Express中正常处理Stripe Webhook,实现代码统一管理。

内容的提问来源于stack exchange,提问作者seth8656

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 07:57:33