admin管理员组

文章数量:1289832

I'm developing an API for my Wordpress website, I want to authorize all API request using jwt token. already installed and configured this plugin "JWT Authentication for WP REST API".But when I try via get/post methode my API will return data with out passing jwt access token how can I prevent this?

function api_version()
{
    $api=array( "version"=> "v1",

    "time"=>date('Y-m-d H:i:s P'));
    return $api;
}

add_action( 'rest_api_init', function () {
  register_rest_route( 'v1/', 'info', array(
    'methods' => 'GET',
    'callback' => 'api_version',

  ) );
} );

I'm developing an API for my Wordpress website, I want to authorize all API request using jwt token. already installed and configured this plugin "JWT Authentication for WP REST API".But when I try via get/post methode my API will return data with out passing jwt access token how can I prevent this?

function api_version()
{
    $api=array( "version"=> "v1",

    "time"=>date('Y-m-d H:i:s P'));
    return $api;
}

add_action( 'rest_api_init', function () {
  register_rest_route( 'v1/', 'info', array(
    'methods' => 'GET',
    'callback' => 'api_version',

  ) );
} );
Share Improve this question asked Oct 24, 2019 at 11:22 Reneesh KurianReneesh Kurian 32 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

The token just authenticates the request as coming from a specific user. You still need to use the permissions callback to check if that user has permission for whatever it is you're doing. If you omit the permissions_callback argument when registering the route then the route is public.

If you only need to check if there is a user, and not specific permissions, you could just use is_user_logged_in():

register_rest_route( 'v1/', 'info', array(
    'methods' => 'GET',
    'callback' => 'api_version',
    'permissions_callback' => function() {
        return is_user_logged_in();
    },
) );

Good Question and not that easy to do propperly (took me 1 week to figure that out).

Then I found 2 good summaries in WordPress docs:
Home / REST API Handbook / Extending the REST API / Routes and Endpoints
Home / REST API Handbook / Extending the REST API / Adding Custom Endpoints

There I found out how to use namespaces, routes and permission_callback correctly.

Critical part was to add the Permission Callback into the function.php of your theme, as @Jacob Peattie mentioned correctly in his answer.

Following, I used the if ( !isset($_COOKIE['wp-postpass_'. COOKIEHASH] )) in the Permission Callback (being the wp-postpass_ cookie the one that holds the token for password protected posts, as an alternative to is_user_logged_in() )

/**
  * This is our callback function to return (GET) our data.
  *
  * @param WP_REST_Request $request This function accepts a rest request to process data.
  */
function get_your_data($request) {
    global $wpdb;
    $yourdata = $wpdb->get_results("SELECT * FROM your_custom_table");

    return rest_ensure_response( $yourdata );
};

/**
 * This is our callback function to insert (POST) new data record.
 *
 * @param WP_REST_Request $request This function accepts a rest request to process data.
 */
function insert_your_data($request) {
    global $wpdb;
    $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';

    if ($contentType === "application/json") {
        $content = trim(file_get_contents("php://input"));
        $decoded = json_decode($content, true);
        $newrecord = $wpdb->insert( 'your_custom_table', array( 'column_1' => $decoded['column_1'], 'column_2' => $decoded['column_2']));
    };
    if($newrecord){
        return rest_ensure_response($newrecord);
    }else{
        //something gone wrong
        return rest_ensure_response('failed');
    };

    header("Content-Type: application/json; charset=UTF-8");
};
/**
 * This is our callback function to update (PUT) a data record.
 *
 * @param WP_REST_Request $request This function accepts a rest request to process data.
 */
function update_your_data($request) {
    global $wpdb;
    $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';

    if ($contentType === "application/json") {
        $content = trim(file_get_contents("php://input"));
        $decoded = json_decode($content, true);
        $updatedrecord = $wpdb->update( 'your_custom_table', array( 'column_1' => $decoded['column_1'], 'column_2' => $decoded['column_2']), array('id' => $decoded['id']), array( '%s' ));
    };

    if($updatedrecord){
        return rest_ensure_response($updatedrecord);
    }else{
        //something gone wrong
        return rest_ensure_response('failed');
    };

    header("Content-Type: application/json; charset=UTF-8");
};

//  Permission Callback 
// 'ypp' is the Prefix I chose (ypp = Your Private Page)

function ypp_get_private_data_permissions_check() {
    // Restrict endpoint to browsers that have the wp-postpass_ cookie.

    if ( !isset($_COOKIE['wp-postpass_'. COOKIEHASH] )) {
       return new WP_Error( 'rest_forbidden', esc_html__( 'OMG you can not create or edit private data.', 'my-text-domain' ), array( 'status' => 401 ) );
    };
    // This is a black-listing approach. You could alternatively do this via white-listing, by returning false here and changing the permissions check.
    return true;
};

// And then add the permission_callback to your POST and PUT routes:

add_action('rest_api_init', function() {
    /**
    * Register here your custom routes for your CRUD functions
    */
    register_rest_route( 'your_private_page/v1', '/data', array(
       array(
          'methods'  => WP_REST_Server::READABLE,
          'callback' => 'get_your_data',
          // Always allow.
          'permission_callback' => '__return_true' // <-- you can protect GET as well if your like
       ),
       array(
          'methods'  => WP_REST_Server::CREATABLE,
          'callback' => 'insert_your_data',
          // Here we register our permissions callback. The callback is fired before the main callback to check if the current user can access the endpoint.
          'permission_callback' => 'ypp_get_private_data_permissions_check', // <-- that was the missing part
       ),
       array(
          'methods'  => WP_REST_Server::EDITABLE,
          'callback' => 'update_your_data',
          // Here we register our permissions callback. The callback is fired before the main callback to check if the current user can access the endpoint.
          'permission_callback' => 'ypp_get_private_data_permissions_check', // <-- that was the missing part
       ),
    ));
});

If you like, I posted a Question (similar issue to yours concerning JWT Authentication) and then my findings in the answer as it worked finally.

Full story with full code at:
How to force Authentication on REST API for Password protected page using custom table and fetch() without Plugin

Hope this helps a little.

本文标签: rest Api jwt authentication for get methodes