admin管理员组

文章数量:1419624

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: /
 */
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.

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/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.

Share Improve this question edited Jul 17, 2019 at 10:06 Muhammad Asif Mohtesham asked Jul 17, 2019 at 6:15 Muhammad Asif MohteshamMuhammad Asif Mohtesham 1432 silver badges9 bronze badges 4
  • 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 Commented Jul 17, 2019 at 6:24
  • I have updated the question to include the relevant code. – Muhammad Asif Mohtesham Commented Jul 17, 2019 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 Commented Jul 17, 2019 at 7:26
  • I hope the additional code helps. – Muhammad Asif Mohtesham Commented Jul 17, 2019 at 8:57
Add a comment  | 

1 Answer 1

Reset to default 8

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/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.

本文标签: