本页面提供了一些在使用 API 时可能遇到的常见问题和问题的解决方案。如果您的问题在此未得到解答,可能在 WordPress 支持论坛 中已有答案。
我可以禁用 REST API 吗?
您不应禁用 REST API;这样做会破坏依赖于 API 处于活动状态的 WordPress Admin 功能。但是,您可以使用过滤器要求 API 消费者进行身份验证,从而有效地阻止匿名外部访问。有关更多信息,请参阅下文。
为所有请求要求身份验证
您可以通过向 rest_authentication_errors 过滤器添加 is_user_logged_in 检查,来为所有 REST API 请求要求身份验证。
注意:传入的回调参数可以是 null、WP_Error 或布尔值。参数的类型表示身份验证的状态:
null:尚未执行身份验证检查,钩子回调可以应用自定义身份验证逻辑。- 布尔值:表示已执行先前的身份验证方法检查。布尔值
true表示请求已成功通过身份验证,布尔值false表示身份验证失败。 WP_Error:遇到某种错误。
add_filter( 'rest_authentication_errors', function( $result ) {
// If a previous authentication check was applied,
// pass that result along without modification.
if ( true === $result || is_wp_error( $result ) ) {
return $result;
}
// No authentication has been performed yet.
// Return an error if user is not logged in.
if ( ! is_user_logged_in() ) {
return new WP_Error(
'rest_not_logged_in',
__( 'You are not currently logged in.' ),
array( 'status' => 401 )
);
}
// Our custom authentication check should have no effect
// on logged-in requests
return $result;
});
我可以在插件内的 PHP 中发起 API 请求吗?
是的,您可以!使用 rest_do_request 在其他 WordPress 代码内部发起 API 请求:
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
// Set one or more request query parameters
$request->set_param( 'per_page', 20 );
$response = rest_do_request( $request );
如何在内部请求中使用 _embed 参数?
在请求对象上设置 _embed 参数将不起作用。
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
$request->set_param( '_embed', 1 );
$response = rest_do_request( $request );
相反,请手动调用 WP_REST_Server::response_to_data 函数。
$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
$response = rest_do_request( $request );
$data = rest_get_server()->response_to_data( $response, true );
var_dump( $data['_embedded'] );
?filter= 查询参数去哪了?
当 REST API 合并到 WordPress 核心时,移除了 ?filter 查询参数,以防止未来的兼容性和维护问题。在 REST API 项目的起源阶段,使用 ?filter 查询参数向 API 传递任意 WP_Query 参数是必要的,但大多数 API 响应过滤功能已被更强大的查询参数(如 ?categories=、?slug= 和 ?per_page=)所取代。
应尽可能使用官方第一方查询参数。但是,如果需要使用,rest-filter 插件可恢复在 API 请求中传递任意 ?filter 值的能力。
查询参数不起作用
如果您发现像 ?page=2 或 ?_embed 这样的查询参数没有任何效果,您的服务器可能未正确配置以检测它们。如果您使用 Nginx 托管网站,请在站点配置中查找 try_files 行。如果它看起来像这样:
try_files $uri $uri/ /index.php$args;
请将其更改为:
try_files $uri $uri/ /index.php$is_args$args;
添加 $is_args(如果发现查询参数将打印 ? 字符)将使 WordPress 能够正确接收和解释查询参数。
为什么身份验证不起作用?
如果您发现正在发送身份验证头信息但请求未被接受,并且您使用的是 CGI 环境,则您的 Web 服务器可能会剥离这些头信息。请尝试添加以下适当的配置以解决此问题。
Apache
将以下内容添加到配置文件或 .htaccess 中:
<IfModule mod_setenvif>
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
</IfModule>
Nginx
将以下内容添加到您的服务器配置的 fastcgi 部分:
fastcgi_pass_header Authorization;
为什么 REST API 不验证传入的 Origin 头信息?这是否会使我的站点面临 CSRF 攻击?
跨域资源共享(CORS)是一种允许网站控制哪些来源(来自外部的站点)可以访问其站点数据的机制。CORS 可防止一种称为跨站请求伪造(CSRF)的特定类型的攻击。但是,WordPress 已经存在一种使用 nonce 的 CSRF 保护机制。收紧 CORS 限制将阻止某些身份验证方法,因此 WordPress REST API 使用 nonce 进行 CSRF 保护,而不是 CORS。
由于 WordPress REST API 不验证传入请求的 Origin 头信息,因此可以从任何站点访问公共 REST API 端点。
这是一个 有意的设计决策,但如果您希望防止未知来源访问您的站点,您可以从 rest_pre_serve_request 过滤器钩子 中取消挂钩默认的 rest_send_cors_headers 函数,然后将您自己的函数挂钩到同一个过滤器,以指定更严格的 CORS 头信息。