REST API custom endpoint without authentication for POST method?

I need a custom WordPress REST API endpoint with POST method to receive some data from external domains. The issue is requests are not authenticated & I can’t apply authentication methods. There is no security issue at all because the data is in a specific format & validated and sanitized in the callback function. Also, data is never saved in DB in the same format. That means, now the endpoint must be public.

Before WordPress 5.5, the below code snippet is working without any issue.

function register_rest_route_check_update() {
    register_rest_route(
        REST_API_NAMESPACE, REST_API_ROUTE,
        array(
            'methods' => 'POST',
            'callback' => array( 'callback_function'),
        )
    );
}

But after WordPress 5.5 update, I got the below message.

Notice: register_rest_route was called incorrectly. The REST API route definition for "abcd" is missing the required permission_callback argument. For REST API routes that are intended to be public, use __return_true as the permission callback.

So I have added permission callback as suggested. Now my code look like below one.

function register_rest_route_check_update() {
    register_rest_route(
        REST_API_NAMESPACE, REST_API_ROUTE,
        array(
            'methods' => 'POST',
            'callback' => array( 'callback_function'),
            'permission_callback' => '__return_true',
        )
    );
}

Now when I submit data to custom API endpoint, I got below message.

{"code":"rest_not_logged_in","message":"You are not currently logged in.","data":{"status":401}}

I believe that this is an authentication error. But I can’t use any authentication method here. So can I make that custom API endpoint as pure public without any authentication?

Also, I have a custom key with me on the submitted data. Can I use that custom key for any authentication?

Note: My intention in using REST API is to make communication between multiple WordPress sites in multiple domains using wp_safe_remote_post & wp_safe_remote_get request. That means some data is submitted into custom REST API endpoint etc.

UPDATE: Consider that the WordPress with custom API endpoint is a server & in client-side, I’m using wp_safe_remote_post() function.

wp_safe_remote_post( $target_url, array('body' => $request_data) )

UPDATE: If I return a false value to rest_authentication_errors filter, there is no further authentication error. But I believe that disabling authentication for all API endpoints may become a security issue later.

add_filter('rest_authentication_errors', '__return_false');

Update: The issue was automatically resolved without any changes in the code or file.

I have attached the code snippet that will be useful for someone else. Public API that accepts POST requests is always vulnerable.

In server-side

add_action( 'rest_api_init', 'register_rest_route_abcd');

function register_rest_route_abcd() {
    register_rest_route(
        'myapi/v1', 'myroute',
        array(
            'methods' => 'POST,GET',
            'callback' => 'my_callback_function',
            'permission_callback' => '__return_true',
        )
    );
}

function my_callback_function($request){
    
    //Do logic here
    
    // Prepare response
    $response = array();
    $response['status'] = true;
    $response['message'] = 'done';
    
    return $response;
}

In clint side

add_action( 'template_redirect', 'ed45r_my_action', 5 );
function ed45r_my_action(){
    
        $target_url="http://localhost/server-sys/wp-json/myapi/v1/myroute";
    
        $data = array(
            'key_1' => 'value_1',
            'key_2' => 'value_2',
        );
        
        $request = wp_safe_remote_get( $target_url, array('body' => $data) );
        
        if(is_wp_error($request) || wp_remote_retrieve_response_code($request) != 200){
            
            // Know the errror
            
        } else {
            
            $response = wp_remote_retrieve_body( $request );
            $response = json_decode($response, true);
            
            // Process the response
            
        }
    
}

In my case, the action is not a template_redirect. It is a form submission.

0

Leave a Comment