0

From what I have tried and tested so far, the getters and setters do not work inside the function permission_callback.

The alternate way would be to throw a custom 401 from the callback itself.

Is it possible to use the permission_callback, check the parameter, and return false instead of writing a custom response in the callback for the same functionality to do a return 401?

Update 1:

permission_callback => function($request) { $request->get_params(); } does not return anything. I need to check the body parameters to allow or deny the request.

Whereas callback => function($request) { $request->get_params(); } returns the parameters correctly, as it should.

Update 2:

In the constructor, $this->init_api(); add_action('wp_enqueue_scripts', array($this, 'api_wholesale_params'));

In init_api,

$this->set_namespace();

$this->set_route();

$this->api_params = array(
    'methods'             => WP_REST_Server::EDITABLE,
    // 'permission_callback' => array($this, "verify_api_call"),
    'callback'            => array($this, "callback")
);

// Set up the API
add_action('rest_api_init', function() {
    register_rest_route($this->namespace, $this->route, $this->api_params);
});


/**
 * Set property: namespace
 * 
 * Source: https://developer.wordpress.org/reference/functions/get_rest_url/
 */
function set_namespace() {
    return $this->namespace = "wholesale/v1/";
}

/**
 * Set property: route
 */
function set_route() {
    return $this->route = "authorise/";
}

/**
 * Localising the API parameters for use in JS
 */
function api_wholesale_params() {
    wp_register_script('api_wholesale', null);
    wp_enqueue_script('api_wholesale');

    wp_localize_script('api_wholesale', 'apiWholesale', array(
        'namespace'         => $this->namespace,
        'route'             => $this->route,
        "url"               => get_rest_url(null, $this->namespace.$this->route),
        "app_id"            => $this->manifest_data['app_id'],
        "ver"               => $this->manifest_data['ver'],
    ));
}

/**
 * Verification of the API call origin
 */
function verify_api_call(WP_REST_Request $req) {
    // $req->get_params(); // returns nothing

    if (array_key_exists('body', $this->params) && array_key_exists('xsrf', $this->params['body'])) {
        // Validate the XSRF token, returns true or false
        $valid_xsrf = $this->verify_xsrf();

        // Returning false would trigger a 401
        return $valid_xsrf ? true : false;
    }
}

// API callback
function callback(WP_REST_Request $req) {
    // Unable to do this in permission_callback
    $this->params        = $req->get_params();

    // Want to do it part using permission_callback
    if ($this->verify_api_call()) {
        return rest_ensure_response($this->res);
    }
}

As you would see, I have commented permission_callback because $request->get_params() does not return anything in verify_api_call. I can, however, call the same $request-get_params() from callback.

  • Can you include examples of what you're talking about? I don't think I understand the difference between what you're want you want to do and what you don't want to do. And what do you mean by "the getters and setters do not work"? What getters and setters? – Jacob Peattie Jul 17 at 6:24
  • I have updated the question to include the relevant code. – Muhammad Asif Mohtesham Jul 17 at 6:53
  • Looking at the source, as far as I can tell, there's no reason $request->get_params(); shouldn't work inside the permission callback. Can you share more information on how you've registered the route, and how you're sending the request? – Jacob Peattie Jul 17 at 7:26
  • I hope the additional code helps. – Muhammad Asif Mohtesham Jul 17 at 8:57
0

I've created a reduced test case that demonstrates that what you want to do is achievable:

add_action( 
    'rest_api_init',
    function() {
        register_rest_route(
            'wpse/343039',
            'route',
            [
                'methods' => [ 'POST' ],
                'permission_callback' => function( WP_REST_Request $request ) {
                    if ( '1' == $request->get_param( 'param' ) ) {
                        return true;
                    } else {
                        return false;
                    }
                },
                'callback' => function( WP_REST_Request $request ) {
                    return rest_ensure_response( '1' );
                },
            ]
        );
    }
);

With this rest route, if I send a POST request to:

https://example.com/wp-json/wpse/343039/route

I will receive a 401 response unless I pass param with the value of 1 in the request body:

{
    "param": 1
}

It can also be passed as form data. If I do pass that parameter, then I see 1 in the response, as expected.

The proper way to return a 401 from a REST endpoint is to return false from the permission_callback function, and as I've demonstrated, you have full access to the request in the callback, so long as you accept it as an argument.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.