Authenticate WP REST API GET Requests

Viewed 6570

Recently I have installed WP REST API on my site and it is working pretty well. But the problem is that the data is accessbile to the public over the open URLs which doesn't reguire authentication. For example a get request to wp-json/wp/v2/posts lists all the post detail to the users.

Is there any way to authenticate the GET Requests to WordPress REST API? I don't want this data is available to anonymous users. Even a basic authentication should work for me!

4 Answers

You need to add a filter in the /wp-includes/default-filters.php

Find this section:

// REST API filters.
add_action( 'xmlrpc_rsd_apis',            'rest_output_rsd' );
add_action( 'wp_head',                    'rest_output_link_wp_head', 10, 0 );
add_action( 'template_redirect',          'rest_output_link_header', 11, 0 );
add_action( 'auth_cookie_malformed',      'rest_cookie_collect_status' );
add_action( 'auth_cookie_expired',        'rest_cookie_collect_status' );
add_action( 'auth_cookie_bad_username',   'rest_cookie_collect_status' );
add_action( 'auth_cookie_bad_hash',       'rest_cookie_collect_status' );
add_action( 'auth_cookie_valid',          'rest_cookie_collect_status' );
add_filter( 'rest_authentication_errors', 'rest_cookie_check_errors', 100 );

Then add a new filter like so:

add_filter( 'rest_authentication_errors', function( $result ) {
        if ( ! empty( $result ) ) {
            return $result;
        }
        if ( ! is_user_logged_in() ) {
            return new WP_Error( 'rest_not_logged_in', 'You are not currently logged in.', array( 'status' => 401 ) );
        }
        return $result;
    });

This solution is mentioned on the WordPress developer resources site, but they do not specifically tell you where to add the filter.

After this change, you should see this message when an un-authenticated user attempts to connect to the REST API:

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

It is possible to restrict by ip

add_filter( 'rest_authentication_errors', 'filter_incoming_connections' );

function filter_incoming_connections( $errors ){

  $allowedAddress = array( '127.0.0.1' );
  $requestServer = $_SERVER['REMOTE_ADDR'];

  if( ! in_array( $requestServer, $allowedAddress ) )
    return new WP_Error( 'forbidden_access', 'Access denied', array( 'status' => 403 ) );

  return $errors;
}

$allowedAddress add authorized ip

Related