Sample code for a RESTful API constructed using WordPress

Here’s an example of a RESTful API built with WordPress that implements token-based authentication for the four main HTTP methods (POST, GET, PUT, DELETE):

<?php
class Sample_REST_API {

    /**
     * Endpoint namespace.
     *
     * @var string
     */
    protected $namespace = 'sample/v1';

    /**
     * Route name.
     *
     * @var string
     */
    protected $route = '/data';

    /**
     * Register the routes for the objects of the controller.
     */
    public function register_routes() {
        register_rest_route( $this->namespace, $this->route, [
            [
                'methods'  => WP_REST_Server::READABLE,
                'callback' => [ $this, 'get_items' ],
                'permission_callback' => [ $this, 'permission_check' ],
            ],
            [
                'methods'  => WP_REST_Server::CREATABLE,
                'callback' => [ $this, 'create_item' ],
                'permission_callback' => [ $this, 'permission_check' ],
            ],
            [
                'methods'  => WP_REST_Server::EDITABLE,
                'callback' => [ $this, 'update_item' ],
                'permission_callback' => [ $this, 'permission_check' ],
            ],
            [
                'methods'  => WP_REST_Server::DELETABLE,
                'callback' => [ $this, 'delete_item' ],
                'permission_callback' => [ $this, 'permission_check' ],
            ],
        ] );
    }

    /**
     * Check if a given request has access to get items.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_Error|bool
     */
    public function permission_check( $request ) {
        $token = $request->get_header( 'token' );

        if ( empty( $token ) || ! $this->validate_token( $token ) ) {
            return new WP_Error( 'rest_forbidden', esc_html__( 'You do not have permission to access this resource.', 'text-domain' ), [ 'status' => 401 ] );
        }

        return true;
    }

    /**
     * Validate token.
     *
     * @param string $token Token.
     *
     * @return bool
     */
    private function validate_token( $token ) {
        // Implement your own token validation logic here.
        return true;
    }

    /**
     * Get a collection of items.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_items( $request ) {
        $data = [
            [ 'id' => 1, 'title' => 'Item 1' ],
            [ 'id' => 2, 'title' => 'Item 2' ],
            [ 'id' => 3, 'title' => 'Item 3' ],
        ];

        $response = rest_ensure_response( $data );

        return $response;
    }

    /**
     * Create one item from the collection.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function create_item( $request ) {
        $item = [
            'id'    => 4,
            'title' => $request->get_param( 'title' ),
        ];

        $response = rest_ensure_response( $item );

        return $response;
    }

    /**
     * Update one item from the collection.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function update_item( $request ) {
        $item = [
            'id'    => $request->get_param( 'id' ),
            'title' => $request->get_param( 'title' ),
        ];

        $response = rest_ensure_response( $item );

        return $response;
    }

    /**
     * Delete one item from the collection.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function delete_item( $request ) {
        $response = rest_ensure_response( true );

        return $response;
    }
}

$sample_rest_api = new Sample_REST_API();
$sample_rest_api->register_routes();
?>

Here’s an updated version of the permission_check function that includes a whitelist of allowed domains:

/**
 * Check if the current request is authorized.
 *
 * @param WP_REST_Request $request Full data about the request.
 *
 * @return bool|WP_Error
 */
public function permission_check( $request ) {
    $header = $request->get_header( 'Authorization' );

    // Check if the Authorization header is present.
    if ( empty( $header ) ) {
        return new WP_Error( 'rest_forbidden', esc_html__( 'You are not authorized to perform this action.' ), [ 'status' => rest_authorization_required_code() ] );
    }

    // Check if the token is valid.
    $token = str_replace( 'Bearer ', '', $header );
    if ( $token !== '1234567890' ) {
        return new WP_Error( 'rest_forbidden', esc_html__( 'You are not authorized to perform this action.' ), [ 'status' => rest_authorization_required_code() ] );
    }

    // Whitelist of allowed domains.
    $allowed_domains = [
        'www.polyxgo.com',
        'api.polyxgo.com',
    ];

    // Get the current domain.
    $current_domain = $request->get_header( 'host' );

    // Check if the current domain is allowed.
    if ( ! in_array( $current_domain, $allowed_domains, true ) ) {
        return new WP_Error( 'rest_forbidden', esc_html__( 'You are not authorized to perform this action.' ), [ 'status' => rest_authorization_required_code() ] );
    }

    return true;
}
?>

This code now checks if the current domain is part of the $allowed_domains array, and returns an error if it’s not. You can modify the array to match your desired list of allowed domains.