Rest V2(WP4.7)では、特定のRESTFUL動詞をどのように制限しますか?


20

カスタム投稿タイプごとに特定のRESTUL動詞を制限することを目指しています。たとえば、語彙のカスタム投稿タイプが与えられた場合、私は言いたいと思います:

許可マトリックス

+-------+---+----------+
|index  | X | GET      |
|show   | O | GET      |
|create | X | POST     |
|update | X | PATCH/PUT|
|delete | X | DELETE   |
+-------+---+----------+

V2はそのレベルの制御を提供していないようです。私はソースを調べましたが、私が見ることができるものから、アクセス権の変更を利用するフック/フィルターはありません。

私の現在の解決策は次のとおりです。許可されたアクションに対してカスタム投稿タイプのマトリックスをロードできるクラスの妥協。これはrest_prepare_vocabularyフィルターで呼び出すことができ、権限が揃っていない場合は応答を破棄します。

問題

これが合理的な解決策だとは思わない。これは、アクセス許可が2つのスポット(まだ適用されているコアの1つ)とフィルターで解決されていることを意味します。

理想的には、構成レベル、つまりカスタム投稿タイプが定義される場所になります。

言い換えると、ポストクエリ "snip"を実行するよりもexclude_from_search、(publicly_queryable、などの行に沿って)ルールを渡すことを好みます。

現在のソリューション(機能するが望ましくない)

Access.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]);
    }
}

functions.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
なぜAccessグローバルスコープでインスタンス化したのですか?他の場所で必要ですか?これにyesと答えた場合、代わりにフィルターに添付することをお勧めします。
カイザー

3
公正な質問-上記はスニペットであり、コンポーザとPSR4オートロードを使用してクラスモジュールを親Appクラスに描画しています。上記のスニペットはその中にあります。したがって、実際にはグローバルではなく\App、アクセスは実際には\App\Services\Access
クリス

1
この問題を自分で調査したことはありませんが、Tracでチケットを確認しましたか、または存在しない場合は作成しましたか?合理的な機能のように
思え

1
私は問題を本当に理解していません。「権限は、2つのスポット(1つ、コア、まだ適用されているので)とフィルターで解決されていることを意味します。理想的には、構成レベル、つまりカスタム投稿タイプが定義されます。ここで何を意味するのか明確にできますか?愚かだとすみません!
ジムマグワイア

2
この質問に賛成票を投じています。18人が賛成した理由がわかりません。不可解です。
ジムマグワイア

回答:


1

私はソースを調べましたが、私が見ることができるものから、アクセス権の変更を利用するフック/フィルターはありません。

私の理解では、これは意図的な設計上の決定でした。

REST APIは拡張可能に構築されていますが、コアエンドポイントを変更することはお勧めできません。

REST APIハンドブックのこのセクションにはいくつかの限られた情報がありますが、その要点は、APIが古くなるにつれて、より多くのコード(コアまたはサードパーティ)が利用可能であり、標準を提供する特定のアクションに依存し始めることです反応。

代わりに、カスタムコントローラーを作成する必要があります。

rest_controller_class引数にregister_post_type()クラス名を指定することで、カスタム投稿タイプにカスタムコントローラーを与えることができます。

カスタムコントローラーの動作方法の概要は、REST APIハンドブックに記載されています

留意すべきことは、WP_REST_Controllerリビジョンをサポートする投稿タイプの抽象クラスを拡張するカスタムコントローラーを作成すると、投稿タイプ固有のリビジョンエンドポイントが自動的に作成されることです。

WP_REST_Controllerクラスを拡張しない場合、register_routes()メソッドは呼び出されないため、カスタムルートを手動で登録する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.