Laravel中PHP如何用RS256算法验证Wix Webhook请求
PHP(Laravel)基于RS256算法实现Wix Webhook签名校验
前置说明
PHP本身原生支持RS256(RSA-SHA256)签名校验,核心能力由内置的openssl扩展提供,不需要额外安装第三方软件包,Laravel框架默认运行环境已满足扩展依赖。
Wix Webhook校验核心逻辑:请求发起方会在请求头携带签名与时间戳,服务端使用Wix提供的RSA公钥,按约定规则拼接待校验内容,通过RS256算法验证签名合法性,同时校验请求时间窗口避免重放攻击。
具体实现步骤
- 第一步:提取请求校验参数
从Wix Webhook请求中提取3个核心校验要素:- 请求头
x-wix-signature:Wix侧生成的RS256签名值 - 请求头
x-wix-timestamp:请求发起的毫秒级Unix时间戳 - 原始请求体:必须取未经框架修改的原始请求内容,不能使用框架解析后的数组/对象参数,否则会因为内容格式变化导致验签失败。
- 请求头
- 第二步:校验请求时间窗口
为避免重放攻击,先校验请求时间是否在允许范围内,常规时间窗口设置为5分钟即可。$timestamp = $request->header('x-wix-timestamp'); $requestTs = floor($timestamp / 1000); // 毫秒时间戳转秒级 if (abs(time() - $requestTs) > 300) { abort(403, 'Webhook request expired'); } - 第三步:构造待验签字符串
按Wix约定的规则拼接待校验内容,格式为时间戳.原始请求体:$rawBody = $request->getContent(); // Laravel获取原始请求体的内置方法 $signingContent = $timestamp . '.' . $rawBody; $signature = $request->header('x-wix-signature'); - 第四步:格式化Wix公钥
从Wix开发者后台获取RS256公钥的裸字符串后,需要转为标准PEM格式才能被openssl函数识别,注意公钥每行长度固定为64字符:// 替换为你从后台获取的Wix公钥裸内容 $wixPublicKeyRaw = 'Wix提供的RS256公钥裸字符串'; $wixPublicKey = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($wixPublicKeyRaw, 64, "\n", true) . "\n-----END PUBLIC KEY-----"; - 第五步:执行RS256验签
调用openssl内置的验签函数完成校验,注意Wix返回的签名是URL安全Base64编码,需要先转成标准Base64格式再解码:// 处理URL安全Base64格式的签名 $decodedSignature = base64_decode(strtr($signature, '-_', '+/')); // RS256对应openssl算法标识为OPENSSL_ALGO_SHA256 $verifyResult = openssl_verify( $signingContent, $decodedSignature, $wixPublicKey, OPENSSL_ALGO_SHA256 ); if ($verifyResult !== 1) { abort(403, 'Invalid webhook signature'); } // 验签通过,继续后续业务逻辑处理
常见问题排查
- 验签始终失败优先检查请求体是否为原始内容,框架自动转JSON、转数组过程中出现的字段顺序调整、空格、编码变化都会导致签名计算不匹配。
- 公钥必须补全PEM格式的头尾标识,且按64字符换行,否则openssl会报公钥无效错误。
- 签名解码前必须替换URL安全Base64的特殊字符,直接解码会导致签名内容错误。
内容的提问来源于stack exchange,提问作者Lokesh Suman
相关产品推荐
相关产品推荐

