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

Starling Bank WebHook签名验证失败:crypto与bodyParser使用疑问

问题分析与解决方案

看起来你的签名验证失败的核心问题在于没有获取到Starling Bank发送的原始请求体,以及中间件配置和代码细节上的小问题。让我一步步帮你排查和修复:

1. 核心问题:bodyParser.json() 默认不会保留原始请求体

当你使用bodyParser.json()时,它会读取并解析请求体为JSON对象,但默认不会保留原始的请求体字符串。而Starling的签名是基于未修改的原始JSON payload计算的——如果你用解析后的req.body或者不正确的rawBody,哈希结果必然和WebHook发送的签名不一致。

2. 修复步骤

步骤1:配置bodyParser保留原始请求体

修改你的Express应用中bodyParser的配置,添加verify选项来把原始请求体保存到req.rawBody:

app.use(bodyParser.json({
  verify: (req, res, buf) => {
    // 将原始请求体Buffer转换为UTF-8字符串保存
    req.rawBody = buf.toString('utf8');
  }
}));

这个配置会让bodyParser在解析JSON的同时,完整保留原始请求体字符串,这是计算正确签名的关键前提。

步骤2:修正签名计算代码

先修复代码中的语法错误(多了一个右括号),再确保用原始请求体和密钥正确计算哈希:

// middleware.js
const functions = require('firebase-functions');
import * as crypto from 'crypto';
// 请确保config已正确导入
import config from './path-to-your-config';

export const auth = (req, res, next) => {
  try {
    // 先检查原始请求体是否存在
    if (!req.rawBody) {
      return res.status(400).send('Missing raw request body');
    }

    // 按Starling规则计算签名:密钥 + 原始请求体的SHA512摘要,再Base64编码
    const hash = crypto.createHash('sha512');
    // 指定UTF-8编码,避免字符串拼接时的编码不一致问题
    hash.update(config.starling.key + req.rawBody, 'utf8');
    const computedSignature = hash.digest('base64');

    const incomingSignature = req.header('X-Hook-Signature');
    if (computedSignature !== incomingSignature) {
      return res.status(403).send('Invalid webhook signature');
    }

    // 签名验证通过,继续执行后续逻辑
    next();
  } catch (err) {
    console.error('Signature verification error:', err);
    return res.status(500).send('Internal server error');
  }
}

步骤3:额外检查点

  • 确认密钥正确性:确保config.starling.key是Starling Bank提供的WebHook密钥,没有多余的空格、换行或拼写错误。
  • 避免提前消耗请求体:确保没有其他中间件(比如自定义日志中间件)在auth中间件之前修改或消耗了请求体。
  • 编码一致性:Starling发送的请求体是UTF-8编码,我们用buf.toString('utf8')保证了编码匹配,不要使用其他编码格式。

为什么之前的代码不对?

  • 你依赖的req.rawBody在默认bodyParser.json()配置下是不存在的,自然无法获取正确的原始请求体。
  • 代码存在语法错误(多了一个右括号),可能导致运行时异常。
  • 没有明确指定编码,可能导致字符串拼接时出现编码不一致的问题。

按照上面的步骤修改后,应该就能正确验证Starling WebHook的签名了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:28:44