FastAPI集成Stripe与Firebase时遇SignatureVerificationError求助
针对你用FastAPI集成Stripe和Firebase时遇到的stripe.error.SignatureVerificationError,本地测试正常但部署后报错的情况,以下是常见原因和解决办法:
1. 检查请求体是否被中间件修改
部署环境(如Firebase Hosting/Cloud Functions)的中间件可能会对请求体进行解析、编码或压缩,导致Stripe发送的原始payload被改动,签名验证自然失败。
解决办法:确保获取原始未修改的请求体。在FastAPI中,await request.body()理论上获取的是原始字节,但如果有中间件先读取了请求体,可能会有问题。可以尝试禁用可能影响请求体的中间件,或者在路由中直接读取原始数据流:
async def feathers_buy_update(request: Request): event = None # 直接读取原始请求体,避免中间件修改 payload = await request.body() sig_header = request.headers.get("stripe-signature") endpoint_secret = "<你的实际端点密钥>" # 替换为部署环境对应的Stripe签名密钥 # 可选:打印payload哈希值,和Stripe控制台Webhook日志里的payload哈希对比,确认是否一致 import hashlib print("Payload SHA-256:", hashlib.sha256(payload).hexdigest()) try: event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret) except stripe.error.SignatureVerificationError as e: print(f"签名验证失败: {str(e)}") raise HTTPException(status_code=400, detail="Invalid signature") # 后续处理Stripe事件逻辑
2. 确认端点密钥完全匹配
确保部署环境使用的endpoint_secret和Stripe控制台中对应Webhook端点的签名密钥完全一致:
- 本地测试用的是Stripe CLI生成的密钥,部署时必须替换为线上Webhook端点的签名密钥
- 不要包含多余的空格、换行或特殊字符,直接复制Stripe控制台的密钥内容
3. 检查请求头传递是否正常
部署环境可能会过滤或修改HTTP请求头,导致stripe-signature头丢失或被篡改。可以在代码中打印sig_header的值,对比Stripe控制台Webhook日志里的签名头是否一致。如果不一致,需要调整部署环境的配置,确保请求头完整传递。
4. 避免不必要的编码操作
虽然你提到payload是bytes类型,但如果部署环境的字符编码设置有问题,可能导致payload被错误解码后重新编码。确保始终以原始字节格式传递给construct_event,不要对payload进行解码再编码的操作(比如payload = payload.decode('utf-8').encode('utf-8'))。
内容的提问来源于stack exchange,提问作者Prakhar Rathi

