在REST V2(WP4.7)中,如何限制某些REST式动词?

时间:2016-12-09 作者:Chris

我的目标是限制每个自定义帖子类型的某些RESTUL动词。例如,给定一个词汇表自定义帖子类型,我想说:

Permission Matrix

+-------+---+----------+
|index  | X | GET      |
|show   | O | GET      |
|create | X | POST     |
|update | X | PATCH/PUT|
|delete | X | DELETE   |
+-------+---+----------+
V2似乎没有提供那种级别的控制。我已经查看了源代码,从我所看到的情况来看,没有任何挂钩/过滤器可用于更改权限。

我目前的解决方案如下。它妥协了一个类,在这个类中,您可以根据允许的操作加载自定义帖子类型的矩阵。然后可以在rest_prepare_vocabulary 筛选,如果权限不一致,则销毁响应。

我觉得这不是一个合理的解决方案。这意味着权限将在两个点(一个在核心,因为它们仍在应用)和我的过滤器中进行解析。

理想情况下,它将处于配置级别,即定义自定义帖子类型的位置。

换句话说,我更愿意通过规则(按照exclude_from_search, publicly_queryable, 等),而不是执行后期查询“剪贴”。

当前解决方案(可行但不可取)

访问。php

class Access
{
    function __construct($permissions) {
        $this->permissions = $permissions;
    }

    protected function hasId($request) {
        return ! is_null($request->get_param(\'id\'));
    }

    protected function resolveType($request) {
        $method = strtoupper($request->get_method());

        if($method === \'GET\' && $this->hasId($request)) {
            return \'show\';
        } else if($method === \'GET\') {
            return \'index\';
        } else if($method === \'DELETE\') {
            return \'delete\';
        } else if($method === \'POST\') {
            return \'create\';
        } else if($method === \'PATCH\') {
            return \'update\';
        }
    }

    function validate($type, $request) {
        return in_array($this->resolveType($request), $this->permissions[$type]);
    }
}

功能。php

// bootstrap the permissions for this particular 
// application
// 
$access = new Access([
    \'vocabulary\' => [\'show\'],
]);

add_filter(\'rest_prepare_vocabulary\', \'validate_permissions\', 30, 3);
function validate_permissions($response, $post, $request) {
    global $access;

    // Give access->validate the type + request data 
    // and it will figure out if this is allowed
    //
    if( ! $access->validate($post->post_type, $request)) {
        $response->set_data([]);
        $response->set_status(403);
    }

    return $response;
};

1 个回复
SO网友:ssnepenthe

我已经查看了源代码,从我所看到的情况来看,没有任何挂钩/过滤器可用于更改权限。

我的理解是,这是一个有意的设计决策。

虽然REST API是为可扩展而构建的,但不建议按照您要求的方式修改核心端点。

中提供的信息有限this section of the REST API handbook, 但其要点是,随着API的老化,更多的代码(无论是核心代码还是第三方代码)将开始依赖于可用的特定操作和提供标准响应。

相反,您应该创建一个自定义控制器。

通过在rest_controller_class argument to register_post_type().

有关自定义控制器应如何工作的概述,请参见REST API handbook.

另外要记住的是,如果您创建一个扩展抽象的自定义控制器WP_REST_Controller 类对于支持修订的帖子类型,将自动创建许多特定于帖子类型的修订端点。

如果没有扩展WP_REST_Controllerregister_routes() 方法,因此您必须手动注册自定义路由。