常见问题

最后更新于:2021-11-28 17:34:41

Frequently Asked Questions

本页面提供了使用API时可能出现的一些常见问题和难题的解决方案。如果您的问题在这里没有解释,它可能已在GeChiUI支持论坛上得到回答。

我可以禁用REST API吗?

您不应该禁用REST API;这样做将破坏取决于API处于活动状态的GeChiUI管理功能。但是,您可以使用过滤器要求API消费者进行身份验证,这有效地防止了匿名外部访问。有关更多信息,请参阅下文。

所有请求都需要身份验证

您可以通过向rest_authentication_errors 筛选器添加 is_user_logged_in 检查来要求对所有 REST API 请求进行身份验证。

注意:传入的回调参数可以是null的、GC_Error或布尔值。参数的类型指示身份验证状态:

  • null:尚未执行身份验证检查,钩子回调可能会应用自定义身份验证逻辑。
  • 布尔值:表示之前执行了身份验证方法检查。布尔true表示请求已成功认证,布尔false表示身份验证失败。
  • GC_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_gc_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 GC_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在其他GeChiUI代码内部提出API请求:

$request = new GC_REST_Request( 'GET', '/gc/v2/posts' );
// Set one or more request query parameters
$request->set_param( 'per_page', 20 );
$response = rest_do_request( $request );

如何在内部请求中使用_embed参数?

在请求对象上设置_embed参数将不起作用。

$request = new GC_REST_Request( 'GET', '/gc/v2/posts' );
$request->set_param( '_embed', 1 );
$response = rest_do_request( $request );

相反,手动调用GC_REST_Server::response_to_data函数。

$request = new GC_REST_Request( 'GET', '/gc/v2/posts' );
$response = rest_do_request( $request );
$data = rest_get_server()->response_to_data( $response, true );
var_dump( $data['_embedded'] );

发生了什么事?filter=查询参数?

当REST API被合并到GeChiUI core中时? ?filter 过滤器查询参数被删除,以防止将来的兼容性和维护问题。在REST API项目的起源阶段,使用 ?filter 过滤器查询参数向API传递任意 GC_Query 参数的能力是必要的,但大多数API响应过滤功能已被更健壮的查询参数所取代,如 ?categories=?slug= 和 ?per_page=.。

应尽可能使用第一方查询参数。但是,如果需要, rest-filter 过滤器插件可以恢复在API请求中传递任意?过滤器值的能力。

查询参数不起作用

如果您发现查询参数,例如?page=2?_embed没有任何效果,您的服务器可能无法正确配置来检测它们。如果您使用Nginx为您的网站服务,请在网站配置中查找atrytry_files行。如果看起来像这样:

try_files $uri $uri/ /index.php$args;

把它改成这样:

try_files $uri $uri/ /index.php$is_args$args;

添加$is_args(将打印一个?如果找到查询参数,字符)将允许GeChiUI正确接收和解释查询参数。

为什么身份验证不起作用?

如果您发现您正在发送身份验证标头,但请求未被接受,并且您正在使用CGI环境,您的Web服务器可能正在剥离标头。请尝试在下面添加适当的配置来解决这个问题。

阿帕奇

将以下内容添加到配置文件或.htaccess中:

<IfModule mod_setenvif>
  SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
</IfModule>

恩吉克斯

将以下内容添加到您的服务器配置fastcgi部分:

fastcgi_pass_header Authorization;

为什么REST API不验证传入的Origin标头?这是否让我的网站面临CSRF攻击?

跨源资源共享(CORS)是一种机制,允许网站控制哪些起源(起源于外部网站)访问您的网站的数据。CORS防止被称为跨站点请求伪造或CSRF的特定类型的攻击。然而,GeChiUI有一个使用nonces的现有CSRF保护机制。收紧CORS限制将阻止某些身份验证方法,因此GeChiUI REST API使用noces作为CSRF保护,而不是CORS。

由于GeChiUI REST API不验证传入请求的Origin标头,因此可以从任何站点访问公共REST API端点。

这是一个有意的设计决策( intentional design decision),但如果您希望阻止从未知来源访问您的站点,您可以从 rest_pre_serve_request filter hook 请求筛选器挂钩中取消默认 rest_send_cors_headers function 函数的挂钩,然后将您自己的函数挂钩到该筛选器,以指定更严格的 CORS 标头。