WP REST API Require Password for GET Endpoint

When we register a rest route with register_rest_route(), then we can use the permission_callback parameter with the kind of permission we want.

Check for example how WP_REST_Posts_Controller::register_routes() and WP_REST_Users_Controller::register_routes() implement the permission callback.

The password argument you’re referring to is the content’s password, that you can set for each post and that’s not the same.

But since you want to target existing routes, like:

/wp/v2/cards
/wp/v2/cards/(?P<id>[\d]+)
/wp/v2/cards/...possibly some other patterns...

you could try e.g. the rest_dispatch_request filter to setup your additional permission check for those kind of routes.

Here’s a demo plugin:

add_filter( 'rest_dispatch_request', function( $dispatch_result, $request, $route, $hndlr )
{
    $target_base="/wp/v2/cards";    // Edit to your needs

    $pattern1 = untrailingslashit( $target_base ); // e.g. /wp/v2/cards
    $pattern2 = trailingslashit( $target_base );   // e.g. /wp/v2/cards/

    // Target only /wp/v2/cards and /wp/v2/cards/*
    if( $pattern1 !== $route && $pattern2 !== substr( $route, 0, strlen( $pattern2 ) ) )
        return $dispatch_result;

    // Additional permission check
    if( is_user_logged_in() )  // or e.g. current_user_can( 'manage_options' )
        return $dispatch_result;

    // Target GET method
    if( WP_REST_Server::READABLE !== $request->get_method() ) 
        return $dispatch_result;

    return new \WP_Error( 
        'rest_forbidden', 
        esc_html__( 'Sorry, you are not allowed to do that.', 'wpse' ), 
        [ 'status' => 403 ] 
    );

}, 10, 4 );

where we target the /wp/v2/cards and /wp/v2/cards/* GET routes, with additional user permission checks.

When debugging it with the WordPress cookie authentication, we can e.g. test it directly with:

https://example.tld/wp-json/wp/v2/cards?_wpnonce=9467a0bf9c

where the nonce part has been generated from wp_create_nonce( 'wp_rest' );

Hope this helps!

Leave a Comment