文章目录[隐藏]
WordPress柔性供应链软件开发中的API安全与防护教程
引言:柔性供应链系统中的API安全挑战
在当今数字化供应链环境中,WordPress作为内容管理系统已扩展至企业级应用,特别是在柔性供应链软件开发中。API(应用程序编程接口)作为系统间数据交换的核心枢纽,其安全性直接关系到整个供应链的稳定性和数据保密性。本教程将深入探讨在WordPress柔性供应链开发中如何实现全面的API安全防护。
一、API认证机制设计与实现
1.1 JWT令牌认证系统
/**
* WordPress柔性供应链API JWT认证类
*/
class SupplyChain_JWT_Auth {
private $secret_key;
public function __construct() {
// 从WordPress配置获取密钥,确保每个环境不同
$this->secret_key = defined('JWT_SECRET_KEY') ? JWT_SECRET_KEY : wp_salt('auth');
}
/**
* 生成JWT令牌
* @param array $user_data 用户数据
* @return string JWT令牌
*/
public function generate_token($user_data) {
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
$payload = json_encode([
'iss' => get_site_url(), // 签发者
'iat' => time(), // 签发时间
'exp' => time() + (24 * 60 * 60), // 24小时过期
'data' => $user_data,
'user_role' => $user_data['role'] // 用户角色用于权限控制
]);
$base64_header = $this->base64url_encode($header);
$base64_payload = $this->base64url_encode($payload);
$signature = hash_hmac('sha256',
$base64_header . "." . $base64_payload,
$this->secret_key,
true
);
$base64_signature = $this->base64url_encode($signature);
return $base64_header . "." . $base64_payload . "." . $base64_signature;
}
/**
* 验证JWT令牌
* @param string $token JWT令牌
* @return array|bool 验证成功返回payload数据,失败返回false
*/
public function validate_token($token) {
$token_parts = explode('.', $token);
if (count($token_parts) != 3) {
return false;
}
list($base64_header, $base64_payload, $base64_signature) = $token_parts;
// 验证签名
$signature = $this->base64url_decode($base64_signature);
$expected_signature = hash_hmac('sha256',
$base64_header . "." . $base64_payload,
$this->secret_key,
true
);
if (!hash_equals($signature, $expected_signature)) {
return false;
}
$payload = json_decode($this->base64url_decode($base64_payload), true);
// 检查令牌是否过期
if (isset($payload['exp']) && $payload['exp'] < time()) {
return false;
}
return $payload;
}
/**
* URL安全的base64编码
*/
private function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
/**
* URL安全的base64解码
*/
private function base64url_decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'),
strlen($data) % 4, '=', STR_PAD_RIGHT));
}
}
1.2 API密钥与OAuth2.0集成
/**
* API密钥管理类
*/
class SupplyChain_API_Key_Manager {
/**
* 生成安全的API密钥对
* @return array 包含API Key和Secret的数组
*/
public function generate_api_keys() {
$api_key = bin2hex(random_bytes(16)); // 32字符的API Key
$api_secret = bin2hex(random_bytes(32)); // 64字符的API Secret
// 在数据库中存储密钥的哈希值
$hashed_secret = wp_hash_password($api_secret);
// 保存到数据库(示例代码)
global $wpdb;
$wpdb->insert(
$wpdb->prefix . 'supplychain_api_keys',
[
'api_key' => $api_key,
'api_secret_hash' => $hashed_secret,
'user_id' => get_current_user_id(),
'created_at' => current_time('mysql'),
'expires_at' => date('Y-m-d H:i:s', strtotime('+90 days')),
'permissions' => json_encode(['read_inventory', 'write_orders'])
]
);
return [
'api_key' => $api_key,
'api_secret' => $api_secret, // 仅在此刻返回明文,之后不再存储
'warning' => '请安全存储API Secret,它将不会再次显示'
];
}
/**
* 验证API请求
*/
public function authenticate_request($api_key, $signature, $request_data) {
// 从数据库获取密钥信息
global $wpdb;
$key_data = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}supplychain_api_keys
WHERE api_key = %s AND status = 'active'",
$api_key
));
if (!$key_data) {
return false;
}
// 验证密钥是否过期
if (strtotime($key_data->expires_at) < time()) {
$this->deactivate_key($api_key);
return false;
}
// 验证签名
$expected_signature = hash_hmac('sha256',
json_encode($request_data),
$key_data->api_secret_hash
);
return hash_equals($signature, $expected_signature);
}
}
二、API请求验证与输入过滤
2.1 请求参数验证类
/**
* API请求验证器
*/
class SupplyChain_API_Validator {
/**
* 验证库存更新请求
*/
public function validate_inventory_request($data) {
$errors = [];
// 验证必需字段
$required_fields = ['product_id', 'quantity', 'warehouse_id'];
foreach ($required_fields as $field) {
if (!isset($data[$field]) || empty($data[$field])) {
$errors[] = "字段 {$field} 是必需的";
}
}
// 验证产品ID格式
if (isset($data['product_id']) && !preg_match('/^PROD-d{6}$/', $data['product_id'])) {
$errors[] = "产品ID格式无效";
}
// 验证数量范围
if (isset($data['quantity']) && (!is_numeric($data['quantity']) || $data['quantity'] < 0 || $data['quantity'] > 10000)) {
$errors[] = "数量必须在0-10000之间";
}
// 验证仓库ID是否存在
if (isset($data['warehouse_id']) && !$this->warehouse_exists($data['warehouse_id'])) {
$errors[] = "指定的仓库不存在";
}
// 清理和转义数据
$cleaned_data = [];
foreach ($data as $key => $value) {
if (is_string($value)) {
$cleaned_data[$key] = sanitize_text_field($value);
} else {
$cleaned_data[$key] = $value;
}
}
return [
'is_valid' => empty($errors),
'errors' => $errors,
'cleaned_data' => $cleaned_data
];
}
/**
* 防止SQL注入的查询方法
*/
public function safe_db_query($query, $params = []) {
global $wpdb;
if (empty($params)) {
return $wpdb->query($query);
}
// 使用WordPress的prepare方法防止SQL注入
$prepared_query = $wpdb->prepare($query, $params);
return $wpdb->query($prepared_query);
}
}
三、速率限制与DDoS防护
3.1 API速率限制器
/**
* API速率限制实现
*/
class SupplyChain_Rate_Limiter {
private $limit;
private $period;
public function __construct($limit = 100, $period = 60) {
$this->limit = $limit; // 请求次数限制
$this->period = $period; // 时间周期(秒)
}
/**
* 检查是否超过速率限制
*/
public function check_limit($api_key, $endpoint) {
$cache_key = 'api_rate_limit_' . md5($api_key . '_' . $endpoint);
$requests = get_transient($cache_key);
if ($requests === false) {
$requests = [];
}
// 清理过期的请求记录
$current_time = time();
$requests = array_filter($requests, function($timestamp) use ($current_time) {
return ($current_time - $timestamp) < $this->period;
});
// 检查是否超过限制
if (count($requests) >= $this->limit) {
return [
'allowed' => false,
'remaining' => 0,
'reset_time' => min($requests) + $this->period
];
}
// 记录当前请求
$requests[] = $current_time;
set_transient($cache_key, $requests, $this->period);
return [
'allowed' => true,
'remaining' => $this->limit - count($requests),
'reset_time' => $current_time + $this->period
];
}
/**
* 智能自适应限流
*/
public function adaptive_rate_limit($api_key, $endpoint) {
// 根据端点重要性设置不同限制
$endpoint_limits = [
'inventory/update' => ['limit' => 50, 'period' => 60],
'orders/create' => ['limit' => 30, 'period' => 60],
'reports/generate' => ['limit' => 10, 'period' => 300]
];
$limits = $endpoint_limits[$endpoint] ?? ['limit' => $this->limit, 'period' => $this->period];
$this->limit = $limits['limit'];
$this->period = $limits['period'];
return $this->check_limit($api_key, $endpoint);
}
}
四、数据加密与安全传输
4.1 端到端数据加密
/**
* 供应链数据加密处理器
*/
class SupplyChain_Data_Encryptor {
private $encryption_key;
private $cipher_method = 'aes-256-gcm';
public function __construct() {
// 从安全配置获取加密密钥
$this->encryption_key = defined('SUPPLYCHAIN_ENCRYPTION_KEY')
? SUPPLYCHAIN_ENCRYPTION_KEY
: $this->generate_encryption_key();
}
/**
* 加密敏感数据
*/
public function encrypt_data($data) {
if (is_array($data)) {
$data = json_encode($data);
}
// 生成随机初始化向量
$iv_length = openssl_cipher_iv_length($this->cipher_method);
$iv = openssl_random_pseudo_bytes($iv_length);
// 加密数据
$encrypted = openssl_encrypt(
$data,
$this->cipher_method,
$this->encryption_key,
OPENSSL_RAW_DATA,
$iv,
$tag
);
// 组合IV、加密数据和认证标签
$result = [
'iv' => base64_encode($iv),
'data' => base64_encode($encrypted),
'tag' => base64_encode($tag),
'cipher' => $this->cipher_method
];
return base64_encode(json_encode($result));
}
/**
* 解密数据
*/
public function decrypt_data($encrypted_string) {
$components = json_decode(base64_decode($encrypted_string), true);
if (!$components || !isset($components['iv'], $components['data'], $components['tag'])) {
return false;
}
$iv = base64_decode($components['iv']);
$data = base64_decode($components['data']);
$tag = base64_decode($components['tag']);
$decrypted = openssl_decrypt(
$data,
$this->cipher_method,
$this->encryption_key,
OPENSSL_RAW_DATA,
$iv,
$tag
);
// 尝试解析JSON,如果不是JSON则返回原始字符串
$result = json_decode($decrypted, true);
return $result ?: $decrypted;
}
}
五、安全监控与日志审计
5.1 API活动日志系统
/**
* API安全日志记录器
*/
class SupplyChain_Security_Logger {
/**
* 记录API请求
*/
public function log_api_request($request_data, $response_data, $user_id = null) {
global $wpdb;
$log_data = [
'timestamp' => current_time('mysql'),
'user_id' => $user_id ?: get_current_user_id(),
'ip_address' => $this->get_client_ip(),
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'endpoint' => $_SERVER['REQUEST_URI'] ?? '',
'method' => $_SERVER['REQUEST_METHOD'] ?? '',
'request_params' => json_encode($this->sanitize_log_data($request_data)),
'response_code' => http_response_code(),
'response_summary' => json_encode($this->sanitize_log_data($response_data, true)),
'risk_level' => $this->assess_risk_level($request_data)
];
$wpdb->insert(
$wpdb->prefix . 'supplychain_api_logs',
$log_data
);
// 高风险请求实时警报
if ($log_data['risk_level'] === 'high') {
$this->send_security_alert($log_data);
}
}
/**
* 风险评估算法
*/
private function assess_risk_level($request_data) {
$risk_score = 0;
// 检查异常参数
$suspicious_patterns = [
'/<script>/i',
'/union.*select/i',
'/drop.*table/i',
'/etc/passwd/i'
];
foreach ($suspicious_patterns as $pattern) {
if (preg_match($pattern, json_encode($request_data))) {
$risk_score += 30;
}
}
// 基于请求频率评估
$request_count = $this->get_recent_request_count();
if ($request_count > 100) {
$risk_score += 20;
}
// 基于时间异常评估(如凌晨2点的批量请求)
$current_hour = date('H');
if ($current_hour >= 2 && $current_hour <= 5) {
$risk_score += 10;
}
if ($risk_score >= 40) return 'high';
if ($risk_score >= 20) return 'medium';
return 'low';
}
}
六、WordPress特定安全配置
6.1 WordPress安全加固配置
/**
* WordPress供应链API安全配置
*/
class WordPress_SupplyChain_Security {
public function init_security_headers() {
// 设置安全HTTP头
add_action('send_headers', function() {
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');
header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
header('Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'');
});
}
/**
* 自定义REST API权限回调
*/
public function secure_rest_api() {
// 限制默认REST API端点访问
add_filter('rest_authentication_errors', function($result) {
if (!empty($result)) {
return $result;
}
// 对供应链端点进行额外验证
if (strpos($_SERVER['REQUEST_URI'], '/wp-json/supplychain/') !== false) {
$auth = new SupplyChain_JWT_Auth();
$token = $this->get_bearer_token();
if (!$token || !$auth->validate_token($token)) {
return new WP_Error(
'rest_forbidden',
'API访问被拒绝:无效或过期的令牌',
['status' => 401]
);
}
}
return $result;
});
}
}
结论:构建多层防御的API安全体系
在WordPress柔性供应链软件开发中,API安全不是单一功能,而是一个多层次、全方位的防御体系。通过实施本文介绍的JWT认证、输入验证、速率限制、数据加密、安全监控和WordPress特定加固措施,您可以构建一个既灵活又安全的供应链API系统。
关键要点总结:
- 认证与授权:使用JWT和API密钥组合,实现细粒度访问控制
- 输入验证:对所有API输入进行严格过滤和验证
- 速率限制:防止API滥用和DDoS攻击
4
七、供应链业务逻辑安全防护
7.1 库存操作原子性与一致性保护
/**
* 供应链库存操作安全处理器
* 确保库存操作的原子性和数据一致性
*/
class SupplyChain_Inventory_Secure_Handler {
/**
* 安全库存扣减方法(防止超卖)
* @param string $product_id 产品ID
* @param int $quantity 扣减数量
* @param int $warehouse_id 仓库ID
* @return array 操作结果
*/
public function safe_inventory_deduction($product_id, $quantity, $warehouse_id) {
global $wpdb;
// 开始数据库事务
$wpdb->query('START TRANSACTION');
try {
// 使用SELECT FOR UPDATE锁定库存记录
$inventory = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}supplychain_inventory
WHERE product_id = %s AND warehouse_id = %d
FOR UPDATE",
$product_id,
$warehouse_id
));
if (!$inventory) {
throw new Exception('库存记录不存在');
}
// 检查库存是否充足(考虑已锁定库存)
$available_stock = $inventory->quantity - $inventory->locked_quantity;
if ($available_stock < $quantity) {
throw new Exception(sprintf(
'库存不足。可用数量:%d,请求数量:%d',
$available_stock,
$quantity
));
}
// 更新库存(原子操作)
$updated = $wpdb->update(
$wpdb->prefix . 'supplychain_inventory',
[
'quantity' => $inventory->quantity - $quantity,
'updated_at' => current_time('mysql'),
'version' => $inventory->version + 1 // 乐观锁版本控制
],
[
'product_id' => $product_id,
'warehouse_id' => $warehouse_id,
'version' => $inventory->version // 确保数据未被其他操作修改
],
['%d', '%s', '%d'],
['%s', '%d', '%d']
);
if ($updated === false) {
throw new Exception('库存更新失败,可能已被其他操作修改');
}
// 记录库存变更流水(用于审计和回滚)
$this->log_inventory_change([
'product_id' => $product_id,
'warehouse_id' => $warehouse_id,
'change_type' => 'deduction',
'quantity' => $quantity,
'before_quantity' => $inventory->quantity,
'after_quantity' => $inventory->quantity - $quantity,
'reference_id' => $this->generate_reference_id(),
'operator_id' => get_current_user_id(),
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? ''
]);
// 提交事务
$wpdb->query('COMMIT');
return [
'success' => true,
'message' => '库存扣减成功',
'remaining_quantity' => $inventory->quantity - $quantity,
'reference_id' => $this->generate_reference_id()
];
} catch (Exception $e) {
// 回滚事务
$wpdb->query('ROLLBACK');
return [
'success' => false,
'message' => '库存扣减失败: ' . $e->getMessage(),
'error_code' => 'INVENTORY_DEDUCTION_FAILED'
];
}
}
/**
* 分布式锁防止并发操作
*/
public function acquire_distributed_lock($lock_key, $timeout = 10) {
$lock_value = uniqid('lock_', true);
$cache_key = 'supplychain_lock_' . md5($lock_key);
// 使用Redis或Memcached实现分布式锁
if (wp_cache_add($cache_key, $lock_value, 'supplychain_locks', $timeout)) {
return $lock_value; // 获取锁成功
}
// 锁已存在,检查是否已过期
$current_lock = wp_cache_get($cache_key, 'supplychain_locks');
if ($current_lock && time() - strtotime($current_lock) > $timeout) {
// 锁已过期,尝试重新获取
wp_cache_delete($cache_key, 'supplychain_locks');
if (wp_cache_add($cache_key, $lock_value, 'supplychain_locks', $timeout)) {
return $lock_value;
}
}
return false; // 获取锁失败
}
}
7.2 供应链数据完整性验证
/**
* 供应链数据完整性验证器
*/
class SupplyChain_Data_Integrity_Validator {
/**
* 验证订单数据完整性
*/
public function validate_order_integrity($order_data) {
$errors = [];
// 1. 验证必填字段
$required_fields = [
'order_number', 'customer_id', 'items', 'total_amount',
'shipping_address', 'payment_method'
];
foreach ($required_fields as $field) {
if (empty($order_data[$field])) {
$errors[] = "必填字段缺失: {$field}";
}
}
// 2. 验证订单项数据
if (isset($order_data['items']) && is_array($order_data['items'])) {
foreach ($order_data['items'] as $index => $item) {
$item_errors = $this->validate_order_item($item, $index);
if ($item_errors) {
$errors = array_merge($errors, $item_errors);
}
}
}
// 3. 验证金额计算正确性
if (isset($order_data['items'], $order_data['total_amount'])) {
$calculated_total = 0;
foreach ($order_data['items'] as $item) {
if (isset($item['unit_price'], $item['quantity'])) {
$calculated_total += $item['unit_price'] * $item['quantity'];
}
}
// 添加税费和运费
$calculated_total += $order_data['tax_amount'] ?? 0;
$calculated_total += $order_data['shipping_cost'] ?? 0;
// 允许0.01的浮点数误差
if (abs($calculated_total - $order_data['total_amount']) > 0.01) {
$errors[] = sprintf(
'金额计算不一致。计算值: %.2f, 提交值: %.2f',
$calculated_total,
$order_data['total_amount']
);
}
}
// 4. 验证业务规则
if (isset($order_data['payment_method'])) {
$allowed_methods = ['credit_card', 'paypal', 'bank_transfer', 'cod'];
if (!in_array($order_data['payment_method'], $allowed_methods)) {
$errors[] = '不支持的支付方式';
}
}
// 5. 生成数据签名验证完整性
$data_signature = $this->generate_data_signature($order_data);
if (!isset($order_data['_signature']) ||
!hash_equals($order_data['_signature'], $data_signature)) {
$errors[] = '数据签名验证失败,数据可能被篡改';
}
return [
'is_valid' => empty($errors),
'errors' => $errors,
'signature' => $data_signature
];
}
/**
* 生成数据完整性签名
*/
private function generate_data_signature($data) {
// 移除签名字段(如果存在)
unset($data['_signature']);
// 按字段名排序确保一致性
ksort($data);
// 递归处理数组
$normalized_data = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// 使用HMAC生成签名
$secret = defined('DATA_INTEGRITY_SECRET')
? DATA_INTEGRITY_SECRET
: wp_salt('data_integrity');
return hash_hmac('sha256', $normalized_data, $secret);
}
}
八、API网关与WAF集成
8.1 WordPress API网关安全层
/**
* WordPress API网关安全中间件
*/
class SupplyChain_API_Gateway {
private $waf_rules = [];
public function __construct() {
$this->load_waf_rules();
}
/**
* API请求预处理中间件
*/
public function preprocess_request() {
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
$request_method = $_SERVER['REQUEST_METHOD'] ?? '';
// 1. 检查请求路径白名单
if (!$this->is_path_allowed($request_uri)) {
$this->block_request(403, '访问路径被禁止');
}
// 2. WAF规则检查
$waf_result = $this->waf_check();
if (!$waf_result['allowed']) {
$this->log_attack_attempt($waf_result);
$this->block_request(403, '请求被WAF拦截');
}
// 3. 请求频率检查
$rate_limit_result = $this->check_rate_limit();
if (!$rate_limit_result['allowed']) {
header('Retry-After: ' . $rate_limit_result['retry_after']);
$this->block_request(429, '请求过于频繁');
}
// 4. 请求体大小限制
if ($this->get_request_body_size() > 10 * 1024 * 1024) { // 10MB限制
$this->block_request(413, '请求体过大');
}
return true;
}
/**
* Web应用防火墙规则检查
*/
private function waf_check() {
$attack_detected = false;
$attack_type = '';
// SQL注入检测
if ($this->detect_sql_injection()) {
$attack_detected = true;
$attack_type = 'SQL Injection';
}
// XSS攻击检测
if ($this->detect_xss_attack()) {
$attack_detected = true;
$attack_type = 'XSS Attack';
}
// 路径遍历检测
if ($this->detect_path_traversal()) {
$attack_detected = true;
$attack_type = 'Path Traversal';
}
// 命令注入检测
if ($this->detect_command_injection()) {
$attack_detected = true;
$attack_type = 'Command Injection';
}
return [
'allowed' => !$attack_detected,
'attack_type' => $attack_type,
'timestamp' => time(),
'ip' => $this->get_client_ip()
];
}
/**
* SQL注入检测
*/
private function detect_sql_injection() {
$patterns = [
'/unions+select/i',
'/select.*from/i',
'/inserts+into/i',
'/updates+set/i',
'/deletes+from/i',
'/drops+table/i',
'/truncates+table/i',
'/--s+/',
'//*.**//',
'/waitfors+delay/i',
'/sleeps*(/i'
];
$input_data = array_merge($_GET, $_POST, $_COOKIE);
foreach ($input_data as $value) {
if (is_string($value)) {
foreach ($patterns as $pattern) {
if (preg_match($pattern, $value)) {
return true;
}
}
}
}
return false;
}
/**
* 动态IP黑名单管理
*/
public function manage_ip_blacklist($ip = null) {
$ip = $ip ?: $this->get_client_ip();
$cache_key = 'supplychain_blocked_ips';
$blocked_ips = get_transient($cache_key);
if (!$blocked_ips) {
$blocked_ips = [];
}
// 检查IP是否在黑名单中
if (in_array($ip, $blocked_ips)) {
$this->block_request(403, 'IP地址已被封禁');
}
// 自动封禁恶意IP
$attack_count = $this->get_ip_attack_count($ip);
if ($attack_count > 10) { // 10次攻击尝试后自动封禁
$blocked_ips[] = $ip;
set_transient($cache_key, $blocked_ips, 24 * 60 * 60); // 封禁24小时
// 记录封禁日志
$this->log_ip_ban($ip, $attack_count);
}
}
}
九、供应链Webhook安全
9.1 安全的Webhook接收与验证
/**
* 供应链Webhook安全处理器
*/
class SupplyChain_Webhook_Security {
/**
* 验证Webhook签名(用于接收第三方通知)
*/
public function verify_webhook_signature($payload, $received_signature, $secret) {
// 1. 验证时间戳防重放攻击
$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
if (empty($timestamp) || abs(time() - $timestamp) > 300) { // 5分钟有效期
return [
'valid' => false,
'error' => 'Webhook时间戳无效或已过期'
];
}
// 2. 验证签名
$expected_signature = $this->calculate_webhook_signature($payload, $timestamp, $secret);
if (!hash_equals($received_signature, $expected_signature)) {
return [
'valid' => false,
'error' => 'Webhook签名验证失败'
];
}
// 3. 验证nonce防重放
$nonce = $_SERVER['HTTP_X_WEBHOOK_NONCE'] ?? '';
if (!$this->validate_nonce($nonce)) {
return [
'valid' => false,
'error' => 'Webhook nonce验证失败'
];
}
return [
'valid' => true,
'timestamp' => $timestamp,
'nonce' => $nonce
];
}
/**
* 计算Webhook签名
*/
private function calculate_webhook_signature($payload, $timestamp, $secret) {
$message = $timestamp . '.' . json_encode($payload, JSON_UNESCAPED_SLASHES);
return hash_hmac('sha256', $message, $secret);
}
/**
* 安全的Webhook处理
*/
public function process_webhook_safely($webhook_data) {
// 1. 异步处理避免超时
$job_id = wp_generate_uuid4();
// 2. 将Webhook数据存入队列
$this->queue_webhook_processing([
'job_id' => $job_id,
'webhook_data' => $webhook_data,
'received_at' => current_time('mysql'),
'source_ip' => $this->get_client_ip(),
'attempts' => 0
]);
// 3. 立即返回响应,避免让调用方等待
return [
'status' => 'accepted',
'job_id' => $job_id,
'message' => 'Webhook已接收,正在处理中',
'check_status_url' => rest_url("supplychain/v1/webhook-status/{$job_id}")
];
}
/**
* Webhook处理工作进程
*/
public function webhook_worker_process($job_data) {
// 1. 验证数据完整性
if (!$this->validate_webhook_data($job_data['webhook_data'])) {
$this->log_webhook_error($job_data, '数据验证失败');
return false;
}
// 2. 幂等性检查(防止重复处理)
if ($this->is_webhook_already_processed($job_data['webhook_data']['event_id'])) {
$this->log_webhook_info($job_data, 'Webhook已处理,跳过');
return true;
}
// 3. 业务逻辑处理(使用事务)
global $wpdb;
$wpdb->query('START TRANSACTION');
try {
// 根据Webhook类型执行不同处理
switch ($job_data['webhook_data']['event_type']) {
case 'order.created':
$this->process_order_created($job_data['webhook_data']);
break;
case 'inventory.updated':
$this->process_inventory_update($job_data['webhook_data']);
break;
case 'shipment.dispatched':
$this->process_shipment_dispatch($job_data['webhook_data']);
break;
default:
throw new Exception('未知的Webhook事件类型');
}
// 标记为已处理
$this->mark_webhook_processed($job_data['webhook_data']['event_id']);
$wpdb->query('COMMIT');
// 记录成功日志
$this->log_webhook_success($job_data);
return true;
} catch (Exception $e) {
$wpdb->query('ROLLBACK');
// 记录错误并重试
$this->log_webhook_error($job_data, $e->getMessage());
// 重试逻辑(最多3次)
if ($job_data['attempts'] < 3) {
$job_data['attempts']++;
$this->retry_webhook_processing($job_data);
}
