Store API 接口的速率限制
速率限制 适用于 Store API 接口。这是一个可选功能,默认情况下是禁用的。可以通过以下说明启用它。
其主要目的是防止对接口的滥用,以及避免因过多的调用而导致运行 Store 的服务器性能下降。
速率限制的跟踪由以下方式控制:用户 ID(已登录用户)、IP 地址(未认证的请求),或者通过过滤器定义的逻辑来识别和分组请求。
它还提供标准的支持,可以在代理服务器、负载均衡器等环境中运行。这也是一个可选功能,默认情况下是禁用的。
UI 控制
目前,此功能仅通过 woocommerce_store_api_rate_limit_options 过滤器进行控制。要通过 UI 进行控制,可以使用以下社区插件:Rate Limiting UI for WooCommerce。
结账速率限制
您可以启用结账“提交订单”操作和 POST /checkout 接口的速率限制,方法是通过 UI 转到 WooCommerce -> 设置 -> 高级 -> 功能,并启用“Rate limiting Checkout block and Store API”。
通过 UI 启用后,速率限制仅适用于 POST /checkout 接口和结账模块的“提交订单”流程。限制为每 60 秒最多 3 个请求。
限制信息
默认情况下,可以在 10 秒的时间范围内最多发出 25 个请求。这些可以通过选项过滤器进行更改。
受速率限制影响的方法
仅对 POST 请求进行速率限制。使用 X-HTTP-Method-Override 头部(例如,通过 wp.apiFetch 发送的 PUT、PATCH 请求)的请求不受到速率限制。
速率限制选项过滤器
提供一个过滤器,用于设置速率限制的选项:
add_filter( 'woocommerce_store_api_rate_limit_options', function() {
return [
'enabled' => false, // 启用/禁用速率限制。默认:false
'proxy_support' => false, // 启用/禁用代理支持。默认:false
'limit' => 25, // 每段时间内的请求限制。默认:25
'seconds' => 10, // 时间范围(秒)。默认:10
];
} );
代理标准支持
如果 Store 运行在代理服务器、负载均衡器、缓存服务、CDN 等之后,通过标准的 IP 转发头来限制基于 IP 的访问是支持的,这些头包括:
X_REAL_IP|CLIENT_IP自定义的常用实现,用于简化获取请求的源 IP 地址X_FORWARDED_FOR用于标识源 IP 地址的事实标准头,文档X_FORWARDED文档, RFC 7239
默认情况下,此功能是禁用的。
启用基于请求自定义指纹的速率限制
对于更高级的用例,您可以启用基于自定义指纹的速率限制。 这允许自定义实现来分组请求,而无需依赖已登录的用户 ID 或 IP 地址。
自定义基本示例,用于通过 User-Agent 和 Accept-Language 组合来分组请求
add_filter( 'woocommerce_store_api_rate_limit_id', function() {
$accept_language = isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) : '';
return md5( wc_get_user_agent() . $accept_language );
} );
限制使用信息的可观察性
当前限制信息可以通过自定义响应头进行观察:
RateLimit-Limit每个时间段的最大请求数。RateLimit-Remaining当前时间段内可用的请求数。RateLimit-Reset下一个时间段重置的 Unix 时间戳。RateLimit-Retry-After直到请求可以再次被允许的时间,以秒为单位。仅在达到限制时显示。
响应头示例
RateLimit-Limit: 5
RateLimit-Remaining: 0
RateLimit-Reset: 1654880642
RateLimit-Retry-After: 28
跟踪限制滥用
此功能使用修改后的 wc_rate_limit 表,其中包含一个额外的 remaining 列,用于跟踪在任何给定的请求窗口内的请求计数。
已实现一个自定义动作 woocommerce_store_api_rate_limit_exceeded,以实现可扩展性,用于跟踪此类滥用行为。
自定义跟踪使用示例
add_action(
'woocommerce_store_api_rate_limit_exceeded',
function ( $offending_ip, $action_id ) { /* 自定义跟踪实现 */ }
);