正在显示
1 个修改的文件
包含
28 行增加
和
9 行删除
| @@ -146,14 +146,24 @@ class PayStripeApi | @@ -146,14 +146,24 @@ class PayStripeApi | ||
| 146 | try { | 146 | try { |
| 147 | // Webhook 签名密钥(从 Stripe 仪表盘获取) | 147 | // Webhook 签名密钥(从 Stripe 仪表盘获取) |
| 148 | $endpointSecret = 'whsec_garhW2TrCIrduyM3rve9mFS2sn69B9Yt'; | 148 | $endpointSecret = 'whsec_garhW2TrCIrduyM3rve9mFS2sn69B9Yt'; |
| 149 | + @file_put_contents(storage_path('logs/lyh_error.log'), var_export($endpointSecret, true) . PHP_EOL, FILE_APPEND); | ||
| 149 | // 获取原始请求内容 | 150 | // 获取原始请求内容 |
| 150 | $payload = request()->getContent(); | 151 | $payload = request()->getContent(); |
| 152 | + @file_put_contents(storage_path('logs/lyh_error.log'), var_export($payload, true) . PHP_EOL, FILE_APPEND); | ||
| 151 | // 获取 Stripe 签名头 | 153 | // 获取 Stripe 签名头 |
| 152 | $sigHeader = request()->header('Stripe-Signature'); | 154 | $sigHeader = request()->header('Stripe-Signature'); |
| 155 | + @file_put_contents(storage_path('logs/lyh_error.log'), var_export($sigHeader, true) . PHP_EOL, FILE_APPEND); | ||
| 153 | // 验证签名 | 156 | // 验证签名 |
| 154 | if (!self::verifySignature($payload, $sigHeader, $endpointSecret)) { | 157 | if (!self::verifySignature($payload, $sigHeader, $endpointSecret)) { |
| 155 | - http_response_code(400); | ||
| 156 | - throw new \Exception('Invalid signature'); | 158 | + return [ |
| 159 | + 'code' => '201', | ||
| 160 | + 'message' => 'Invalid signature', | ||
| 161 | + 'details' => [ | ||
| 162 | + 'payload' => $payload, | ||
| 163 | + 'sigHeader' => $sigHeader, | ||
| 164 | + 'endpointSecret' => $endpointSecret, | ||
| 165 | + ], | ||
| 166 | + ]; // 返回 400 Bad Request 状态码; | ||
| 157 | } | 167 | } |
| 158 | $event = json_decode($payload, true); | 168 | $event = json_decode($payload, true); |
| 159 | // 获取事件类型 | 169 | // 获取事件类型 |
| @@ -193,14 +203,23 @@ class PayStripeApi | @@ -193,14 +203,23 @@ class PayStripeApi | ||
| 193 | */ | 203 | */ |
| 194 | public static function verifySignature($payload, $sigHeader, $endpointSecret) | 204 | public static function verifySignature($payload, $sigHeader, $endpointSecret) |
| 195 | { | 205 | { |
| 196 | - // 获取 Stripe 签名 | ||
| 197 | - $signatures = []; | ||
| 198 | - if (preg_match_all('/t=\d+,v1=([a-f0-9]+)/', $sigHeader, $matches)) { | ||
| 199 | - $signatures = $matches[1]; | 206 | + // 解析 Signature Header,获取 timestamp 和签名 |
| 207 | + if (!preg_match('/t=(\d+),v1=([a-f0-9]+)/', $sigHeader, $matches)) { | ||
| 208 | + return false; // 签名格式错误 | ||
| 200 | } | 209 | } |
| 201 | - // 计算签名哈希值 | ||
| 202 | - $expectedSignature = hash_hmac('sha256', $payload, $endpointSecret); | ||
| 203 | - return in_array($expectedSignature, $signatures, true); | 210 | + $timestamp = $matches[1]; // 提取时间戳 |
| 211 | + $receivedSignature = $matches[2]; // 提取签名 | ||
| 212 | + // 防止重放攻击:检查时间戳是否在 5 分钟以内 | ||
| 213 | + $currentTimestamp = time(); | ||
| 214 | + if (abs($currentTimestamp - $timestamp) > 300) { | ||
| 215 | + return false; // 签名过期 | ||
| 216 | + } | ||
| 217 | + // 计算预期签名 | ||
| 218 | + $signedPayload = "{$timestamp}.{$payload}"; | ||
| 219 | + $expectedSignature = hash_hmac('sha256', $signedPayload, $endpointSecret); | ||
| 220 | + // 比较签名是否匹配 | ||
| 221 | + return hash_equals($expectedSignature, $receivedSignature); | ||
| 204 | } | 222 | } |
| 205 | 223 | ||
| 224 | + | ||
| 206 | } | 225 | } |
-
请 注册 或 登录 后发表评论