如何限制WooCommerce API权限,仅允许产品只读访问?
Great question! Since the plugin you found is outdated and has very low usage, building a custom solution is definitely the safer and more reliable path. Here are a few proven approaches to restrict your WooCommerce API to read-only access for product-related endpoints:
1. Use WooCommerce's Built-in API Permission Filter (Recommended)
WooCommerce provides a dedicated hook woocommerce_rest_check_permissions that lets you override API access permissions. This approach targets WooCommerce-specific API requests directly, making it precise and easy to maintain.
Add this code to your theme's functions.php file or a custom plugin:
add_filter('woocommerce_rest_check_permissions', 'restrict_api_to_product_read_only', 10, 4); function restrict_api_to_product_read_only($permission, $context, $object_id, $post_type) { // Get the current REST request object $request = wc_get_rest_request(); if (!$request) return $permission; // Define all product-related read-only routes you want to allow $allowed_routes = array( '/wc/v3/products', '/wc/v3/products/(?P<id>[\d]+)', '/wc/v3/products/categories', '/wc/v3/products/categories/(?P<id>[\d]+)', '/wc/v3/products/tags', '/wc/v3/products/tags/(?P<id>[\d]+)', // Add any other product-related read endpoints you need here ); $current_route = $request->get_route(); $is_allowed_route = false; // Check if the current route matches any allowed pattern foreach ($allowed_routes as $route_pattern) { if (preg_match('#^' . $route_pattern . '$#', $current_route)) { $is_allowed_route = true; break; } } // Ensure the request uses a read-only HTTP method (GET) $is_read_method = in_array($request->get_method(), array('GET')); // Block access if the route isn't allowed OR the method isn't read-only if (!$is_allowed_route || !$is_read_method) { return new WP_Error( 'rest_forbidden', __('You do not have permission to access this endpoint.', 'woocommerce'), array('status' => rest_authorization_required_code()) ); } // For allowed requests, keep the original permission check (ensures the user has basic read access) return $permission; }
How it works:
- This hook intercepts every WooCommerce API permission check
- It only allows
GETrequests to the specified product/category/tag endpoints - Any other request (e.g.,
POST/PUTto products, or any request to orders/customers) will return a403 Forbiddenerror
2. Use WP REST API's Global Authentication Filter
If you want a more low-level approach that applies to all REST API requests (not just WooCommerce), use the rest_authentication_errors hook. This runs early in the request lifecycle, making it a stricter option.
Add this code to your theme's functions.php or custom plugin:
add_filter('rest_authentication_errors', 'restrict_rest_api_to_product_read'); function restrict_rest_api_to_product_read($result) { // If authentication already failed, return the existing error if (!empty($result)) return $result; $request = wp_rest_server()->get_current_request(); if (!$request) return $result; // Map allowed routes to their allowed HTTP methods $allowed_endpoints = array( '/wc/v3/products' => array('GET'), '/wc/v3/products/(?P<id>[\d]+)' => array('GET'), '/wc/v3/products/categories' => array('GET'), '/wc/v3/products/categories/(?P<id>[\d]+)' => array('GET'), '/wc/v3/products/tags' => array('GET'), '/wc/v3/products/tags/(?P<id>[\d]+)' => array('GET'), ); $current_route = $request->get_route(); $current_method = $request->get_method(); // Check if the current request matches any allowed endpoint/method pair foreach ($allowed_endpoints as $route_pattern => $allowed_methods) { if (preg_match('#^' . $route_pattern . '$#', $current_route) && in_array($current_method, $allowed_methods)) { // Allow the request to proceed with normal authentication return $result; } } // Block all other requests with a 403 error return new WP_Error( 'rest_forbidden', __('Access restricted to product read-only endpoints.', 'text-domain'), array('status' => 403) ); }
3. Create a Custom API User Role
If you need to restrict access to specific users (e.g., a third-party service that only needs product data), create a custom WordPress role with limited WooCommerce capabilities.
Add this code to a custom plugin (not recommended for theme functions.php, as roles won't persist if you switch themes):
// Create the custom role when the plugin is activated register_activation_hook(__FILE__, 'create_product_api_only_role'); function create_product_api_only_role() { add_role( 'product_api_user', __('Product API User', 'text-domain'), array( 'read' => true, // Required for basic WordPress REST access 'read_products' => true, 'read_product' => true, 'read_product_categories' => true, 'read_product_tags' => true, // Explicitly exclude all other WooCommerce capabilities (edit_products, read_orders, etc.) ) ); } // Optional: Disable WooCommerce API access for all non-product API users add_filter('woocommerce_rest_api_enabled', 'block_api_for_non_product_roles'); function block_api_for_non_product_roles($enabled) { $current_user = wp_get_current_user(); if ($current_user && !in_array('product_api_user', $current_user->roles)) { return false; } return $enabled; }
How to use:
- Install and activate the custom plugin
- Create a new user in WordPress and assign them the "Product API User" role
- Generate API keys for this user in WooCommerce > Settings > Advanced > REST API
- This user will only have access to product-related read endpoints
Testing Tips
After implementing any of these solutions, test with tools like Postman or curl to verify:
GET /wc/v3/productsshould return a 200 OK responsePOST /wc/v3/products(trying to create a product) should return 403 ForbiddenGET /wc/v3/ordersshould return 403 Forbidden
内容的提问来源于stack exchange,提问作者user1688928

