是否可以添加使用 WooCommerce 授权的新 API 端点?
Is it possible to add a new API endpoint that uses WooCommerce's authorization?
我需要在我的 WordPress 插件中添加一个 API 端点,它将写入数据库等。我希望它由调用这个新 API 的远程系统触发。
但是,我想使用内置的 WooCommerce REST 身份验证,这里设置的身份验证:
(不,这些凭据不再有效)。
有办法吗?要添加将使用 WooCommerce 的身份验证的自定义 HTTP 端点,然后 运行 我想要的一些任意代码 运行?
或者有没有一种方法可以在现有 WooCommerce API 端点上添加一个钩子到 运行 端点执行之前?我只需要一种方法来使用现有的 WooCommerce REST API 身份验证来触发我需要在我的插件中 运行 的一些更新。
您可以在 Woocommerce 端点下添加路由以使用此 key/secret 身份验证系统。
这是一个工作示例:
add_action('rest_api_init', function () {
register_rest_route('wc', '/test', [
'methods' => 'GET',
'callback' => 'my_awesome_func',
]);
});
function my_awesome_func(WP_REST_Request $request)
{
if (is_user_logged_in() && (int)wp_get_current_user()->ID === 123) {
//your stuff only for legged in user 123
return new WP_REST_Response('ok', 200);
}
return new WP_Error('unauthorized', __('You shall not pass'), [ 'status' => 401 ]); //can also use WP_REST_Response
}
这将:
- 在“wc”端点(woocommerce one)下添加一个新的 GET 路由,所以
https://example.com/wp-json/wc/test
- 然后您使用“HTTP Basic auth”根据 Woocommerce documentation
传递您的密钥和秘密
is_user_logged_in()
和 wp_get_current_user()
的结果将取决于 key/secret 的正确组合。如果正确,关联的用户将被“认证”为 Wordpress。
- 如果组合正确,你会得到
[true, WP_user_object]
,如果组合不正确,你会得到 [false, Empty_user_object]
。
- 如果正确的密钥和不正确的秘密,将抛出 401(不是我示例中的那个,是 woocommerce 的另一个 401。在这种情况下未达到
my_awesome_func()
。我相信这就像 wp-login,正确登录(密钥)时的自定义错误消息,很好 ^^')
然后您需要按照您的规则保护您的路线:
- 像
if(!is_user_logged_in()) return false
一样检查用户是否登录
- 正在检查用户 ID
wp_get_current_user()->ID
- 正在通过您的 role/permission 系统检查
- 现在你有了用户 ID,你可以用它做你想做的事
- 使用
WP_REST_Request $request
参数处理 GET 或 POST HTTP 参数。
所以它看起来像:
add_action('rest_api_init', function () {
register_rest_route('wc', '/test', [
'methods' => 'GET',
'callback' => 'my_awesome_func',
]);
});
function my_awesome_func(WP_REST_Request $request)
{
if (is_user_logged_in() && (int)wp_get_current_user()->ID === 123) {
//your stuff only for legged in user 123
return new WP_REST_Response('ok', 200);
}
return new WP_Error('unauthorized', __('You shall not pass'), [ 'status' => 401 ]); //can also use WP_REST_Response
}
似乎可以 添加 Woocommerce REST API 端点(找不到关于它的适当文档...)。但我对此进行了测试并且它有效,至少可以使用 Woocommerce key/Secret 身份验证系统,我相信它是在 /wc/
端点下应用的。
注意:小心地将路由添加到 wc 端点,因为您可能会覆盖现有的路由端点。例如:添加 /product/mytest
可能与处理 /product/[product_id]
.
的官方 Woocommerce 路由冲突
注2:我先用一个custom WordPress REST API route, and passing Woocommerce key/secret to see if WordPress could see me correctly authenticated and identified. But it didn't work (WP uses the core API auth system)进行了测试。所以我搬到了 Woocommerce API 端点。
注意 3:您可以使用带有自定义路由的 Wordpress REST API 和“机器对机器”身份验证插件(如 Oauth、应用程序密码、JWT...)实现相同的效果,如 WP REST API authentication documentation page.
有点晚了,但通过反射我们可以使用 WC 身份验证逻辑来验证自定义 API 路由。
add_action( 'rest_api_init', function () {
/**
* Register here your custom routes for your CRUD functions
*/
register_rest_route( 'test/', 'wc-permissions', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'read_check',
'permission_callback' => 'do_wc_basic_auth_permission_check'
),
array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => 'write_check',
'permission_callback' => 'do_wc_basic_auth_permission_check',
),
) );
} );
/**
* Perform check via official WC REST auth class by reflecting method accessibility.
* Uses official auth class, so it triggers all hooks as on normal 'wp-json/wc/v3/' routes
*
* @return bool
* @throws ReflectionException
*/
function validate_request_has_valid_wc_api_keys(): bool {
// WC not enabled, target reflection class is probably not registered
if ( ! function_exists( 'WC' ) ) {
return false;
}
$method = new ReflectionMethod( 'WC_REST_Authentication', 'perform_basic_authentication' );
$method->setAccessible( true );
return $method->invoke( new WC_REST_Authentication ) !== false;
}
function write_check() {
return 'can create new entry via POST';
}
function read_check() {
return 'can get entry content via GET';
}
如果您想将此身份验证检查添加到全局其他路由,f.e。核心 WP 路由,您可以使用 add_filter('rest_dispatch_request', function ( $intendedResponse, $request, $route )
过滤器并尝试将传递的 $route
参数与正则表达式或其他方式匹配。
只需投入我的两分钱...
我想知道是否有另一种方法可以添加一个新的 API 端点,它使用 WooCommerce 消费者密钥和秘密授权,避免与 WooCommerce /wc/
端点可能发生的冲突,并且不求助于使用反射。
答案在WC_REST_Authentication
class 中包含的is_request_to_rest_api
函数中。为了使用 WooCommerce 身份验证方法,third-party 插件的端点命名空间应以 wc-
.
开头
例如:
add_action( 'rest_api_init', function() {
register_rest_route(
'wc-myprefix/v1',
'/orders/(?P<order_id>\d+)/shipment-trackings',
array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'get_shipment_trackings',
'permission_callback' => 'check_permission',
),
);
});
function get_shipment_trackings( WP_REST_Request $request ) {
// return shipment trackings
}
function check_permission() {
if ( ! current_user_can( 'read_private_shop_orders' ) ) {
return new WP_Error( 'woocommerce_rest_cannot_view',
__( 'Sorry, you cannot list resources.', 'myprefix' ),
array( 'status' => rest_authorization_required_code() ) );
}
return true;
}
请注意新路由的wc-myprefix/v1
命名空间(以wc-
开头),以及权限回调中current_user_can
函数的使用。触发实际身份验证的是对此函数的调用。
如果您像我一样不想让任何人告诉您端点命名空间应该如何命名,那么可以使用一个方便的过滤器 (woocommerce_rest_is_request_to_rest_api
) 来实现您自己的逻辑确定调用是否为休息 API 端点(即检查您自己的特定端点命名空间)。
我需要在我的 WordPress 插件中添加一个 API 端点,它将写入数据库等。我希望它由调用这个新 API 的远程系统触发。
但是,我想使用内置的 WooCommerce REST 身份验证,这里设置的身份验证:
(不,这些凭据不再有效)。
有办法吗?要添加将使用 WooCommerce 的身份验证的自定义 HTTP 端点,然后 运行 我想要的一些任意代码 运行?
或者有没有一种方法可以在现有 WooCommerce API 端点上添加一个钩子到 运行 端点执行之前?我只需要一种方法来使用现有的 WooCommerce REST API 身份验证来触发我需要在我的插件中 运行 的一些更新。
您可以在 Woocommerce 端点下添加路由以使用此 key/secret 身份验证系统。
这是一个工作示例:
add_action('rest_api_init', function () {
register_rest_route('wc', '/test', [
'methods' => 'GET',
'callback' => 'my_awesome_func',
]);
});
function my_awesome_func(WP_REST_Request $request)
{
if (is_user_logged_in() && (int)wp_get_current_user()->ID === 123) {
//your stuff only for legged in user 123
return new WP_REST_Response('ok', 200);
}
return new WP_Error('unauthorized', __('You shall not pass'), [ 'status' => 401 ]); //can also use WP_REST_Response
}
这将:
- 在“wc”端点(woocommerce one)下添加一个新的 GET 路由,所以
https://example.com/wp-json/wc/test
- 然后您使用“HTTP Basic auth”根据 Woocommerce documentation 传递您的密钥和秘密
is_user_logged_in()
和wp_get_current_user()
的结果将取决于 key/secret 的正确组合。如果正确,关联的用户将被“认证”为 Wordpress。- 如果组合正确,你会得到
[true, WP_user_object]
,如果组合不正确,你会得到[false, Empty_user_object]
。 - 如果正确的密钥和不正确的秘密,将抛出 401(不是我示例中的那个,是 woocommerce 的另一个 401。在这种情况下未达到
my_awesome_func()
。我相信这就像 wp-login,正确登录(密钥)时的自定义错误消息,很好 ^^')
然后您需要按照您的规则保护您的路线:
- 像
if(!is_user_logged_in()) return false
一样检查用户是否登录
- 正在检查用户 ID
wp_get_current_user()->ID
- 正在通过您的 role/permission 系统检查
- 现在你有了用户 ID,你可以用它做你想做的事
- 使用
WP_REST_Request $request
参数处理 GET 或 POST HTTP 参数。
所以它看起来像:
add_action('rest_api_init', function () {
register_rest_route('wc', '/test', [
'methods' => 'GET',
'callback' => 'my_awesome_func',
]);
});
function my_awesome_func(WP_REST_Request $request)
{
if (is_user_logged_in() && (int)wp_get_current_user()->ID === 123) {
//your stuff only for legged in user 123
return new WP_REST_Response('ok', 200);
}
return new WP_Error('unauthorized', __('You shall not pass'), [ 'status' => 401 ]); //can also use WP_REST_Response
}
似乎可以 /wc/
端点下应用的。
注意:小心地将路由添加到 wc 端点,因为您可能会覆盖现有的路由端点。例如:添加 /product/mytest
可能与处理 /product/[product_id]
.
注2:我先用一个custom WordPress REST API route, and passing Woocommerce key/secret to see if WordPress could see me correctly authenticated and identified. But it didn't work (WP uses the core API auth system)进行了测试。所以我搬到了 Woocommerce API 端点。
注意 3:您可以使用带有自定义路由的 Wordpress REST API 和“机器对机器”身份验证插件(如 Oauth、应用程序密码、JWT...)实现相同的效果,如 WP REST API authentication documentation page.
有点晚了,但通过反射我们可以使用 WC 身份验证逻辑来验证自定义 API 路由。
add_action( 'rest_api_init', function () {
/**
* Register here your custom routes for your CRUD functions
*/
register_rest_route( 'test/', 'wc-permissions', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'read_check',
'permission_callback' => 'do_wc_basic_auth_permission_check'
),
array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => 'write_check',
'permission_callback' => 'do_wc_basic_auth_permission_check',
),
) );
} );
/**
* Perform check via official WC REST auth class by reflecting method accessibility.
* Uses official auth class, so it triggers all hooks as on normal 'wp-json/wc/v3/' routes
*
* @return bool
* @throws ReflectionException
*/
function validate_request_has_valid_wc_api_keys(): bool {
// WC not enabled, target reflection class is probably not registered
if ( ! function_exists( 'WC' ) ) {
return false;
}
$method = new ReflectionMethod( 'WC_REST_Authentication', 'perform_basic_authentication' );
$method->setAccessible( true );
return $method->invoke( new WC_REST_Authentication ) !== false;
}
function write_check() {
return 'can create new entry via POST';
}
function read_check() {
return 'can get entry content via GET';
}
如果您想将此身份验证检查添加到全局其他路由,f.e。核心 WP 路由,您可以使用 add_filter('rest_dispatch_request', function ( $intendedResponse, $request, $route )
过滤器并尝试将传递的 $route
参数与正则表达式或其他方式匹配。
只需投入我的两分钱...
我想知道是否有另一种方法可以添加一个新的 API 端点,它使用 WooCommerce 消费者密钥和秘密授权,避免与 WooCommerce /wc/
端点可能发生的冲突,并且不求助于使用反射。
答案在WC_REST_Authentication
class 中包含的is_request_to_rest_api
函数中。为了使用 WooCommerce 身份验证方法,third-party 插件的端点命名空间应以 wc-
.
例如:
add_action( 'rest_api_init', function() {
register_rest_route(
'wc-myprefix/v1',
'/orders/(?P<order_id>\d+)/shipment-trackings',
array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'get_shipment_trackings',
'permission_callback' => 'check_permission',
),
);
});
function get_shipment_trackings( WP_REST_Request $request ) {
// return shipment trackings
}
function check_permission() {
if ( ! current_user_can( 'read_private_shop_orders' ) ) {
return new WP_Error( 'woocommerce_rest_cannot_view',
__( 'Sorry, you cannot list resources.', 'myprefix' ),
array( 'status' => rest_authorization_required_code() ) );
}
return true;
}
请注意新路由的wc-myprefix/v1
命名空间(以wc-
开头),以及权限回调中current_user_can
函数的使用。触发实际身份验证的是对此函数的调用。
如果您像我一样不想让任何人告诉您端点命名空间应该如何命名,那么可以使用一个方便的过滤器 (woocommerce_rest_is_request_to_rest_api
) 来实现您自己的逻辑确定调用是否为休息 API 端点(即检查您自己的特定端点命名空间)。