如何在插件渲染的React组件中调用WooCommerce REST API?API密钥该如何处理?
正确处理WooCommerce REST API前端认证的方案
首先要明确:你当前代码里把consumer_key和consumer_secret直接写在前端URL里是严重的安全漏洞——任何查看页面源码的人都能拿到这些密钥,进而完全控制你的WooCommerce商店,绝对不能这么做。
最优方案是通过WordPress后端做请求代理:前端只请求你自己注册的WordPress自定义REST路由,由后端代为调用WooCommerce API并返回结果,这样密钥全程只在后端存储,不会暴露给前端。
步骤1:在插件后端注册自定义REST路由
在你的插件PHP文件里添加以下代码,注册一个代理WooCommerce产品请求的路由:
add_action('rest_api_init', function () { register_rest_route( 'your-plugin/v1', '/products', [ 'methods' => WP_REST_Server::READABLE, 'callback' => 'your_plugin_proxy_wc_products', 'permission_callback' => function () { // 这里可以根据需求设置权限,比如允许所有访客访问就返回true return true; // 如果需要登录用户才能访问,用:return is_user_logged_in(); }, ] ); }); function your_plugin_proxy_wc_products() { // WooCommerce API 配置 $consumer_key = 'ck_123456789'; // 这里填你的真实密钥,安全存储在后端 $consumer_secret = 'cs_987654321'; $wc_api_url = get_rest_url(null, 'wc/v3/products'); // 生成Basic Auth头(WooCommerce API支持Basic认证) $auth = base64_encode("$consumer_key:$consumer_secret"); $headers = [ 'Authorization' => "Basic $auth", 'Content-Type' => 'application/json', ]; // 调用WooCommerce API $response = wp_remote_get($wc_api_url, [ 'headers' => $headers, 'timeout' => 10, ]); // 处理响应 if (is_wp_error($response)) { return new WP_Error('wc_api_error', '请求WooCommerce API失败', ['status' => 500]); } $body = wp_remote_retrieve_body($response); $status_code = wp_remote_retrieve_response_code($response); return new WP_REST_Response(json_decode($body), $status_code); }
步骤2:修改前端代码请求自定义路由
把前端的请求URL改成你注册的自定义路由,同时保留WordPress的nonce认证确保请求合法性:
import { useState, useEffect } from "@wordpress/element"; export default function Block() { const [products, setProducts] = useState([]); const fetchProducts = async () => { // 使用WordPress提供的REST根URL + 自定义路由 const url = `${wpApiSettings.root}your-plugin/v1/products`; const response = await fetch(url, { method: "GET", credentials: "same-origin", headers: { "Content-Type": "application/json", "X-WP-Nonce": wpApiSettings.nonce, }, }); if (!response.ok) { throw new Error("Unable to Retrieve Data. Please try again."); } return response.json(); }; useEffect(() => { fetchProducts() .then((data) => { setProducts([...data]); }) .catch((err) => { console.error(err.message); }); }, []); if (!products.length) { return <div>loading</div>; } function strip(html) { let doc = new DOMParser().parseFromString(html, "text/html"); return doc.body.textContent || ""; } const items = products.map((prod) => ( <li key={prod.id}> <img src={prod.images[0].src} alt={prod.name} /> <h1>{prod.name}</h1> <p>{strip(prod.short_description)}</p> <h2>{prod.price}</h2> <button> {prod.button_text !== "" ? prod.button_text : "Add To Cart"} </button> </li> )); return <ul>{items}</ul>; }
为什么这个方案是最优的?
- 安全性:密钥完全保存在后端,前端永远不会接触到,避免了泄露风险。
- 可控性:通过
permission_callback可以灵活控制谁能访问这个代理路由(比如只允许登录用户、特定角色用户)。 - 兼容性:完全遵循WordPress和WooCommerce的开发规范,不会引入额外的依赖或复杂的认证流程。
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

