Ocultar los puntos finales v2 de REST de WordPress de la visualización pública

8

Me gustaría comenzar a usar la WordPress REST API v2 para consultar información de mi sitio. Me he dado cuenta de que cuando visito una URL de punto final directamente, puedo ver todos los datos públicamente. También he visto que muchos tutoriales mencionan el uso de servidores de prueba o locales en lugar de los sitios activos.

Mis preguntas son:

  • ¿Está destinado a ser utilizado en sitios en producción?
  • ¿Hay una seguridad riesgo de permitir que los puntos finales sean vistos por cualquier persona, como /wp-json/wp/v2/users/ que muestra todos los usuarios registrados en el sitio?
  • ¿Es posible permitir que solo usuarios autorizados accedan a un punto final?

Quiero asegurarme de que estoy siguiendo las mejores prácticas en materia de seguridad, por lo que cualquier consejo sería útil. La api docs menciona la autenticación, pero no estoy seguro de cómo evitar que se acceda directamente a la URL. ¿Cómo suelen otras personas configurar estos datos para que accedan a las aplicaciones externas sin exponer demasiada información?

    
pregunta Morgan 02.06.2016 - 17:39

4 respuestas

12
  

¿Está destinado a ser utilizado en sitios en producción?

¡Sí! Muchos sitios ya lo han estado utilizando .

  

¿Existe algún riesgo de seguridad para permitir que cualquier persona vea los puntos finales, como / wp-json / wp / v2 / users / que muestra a todos los usuarios registrados en el sitio?

¡No! Las respuestas del servidor no tienen nada que ver con la seguridad, ¿qué puede hacer con una pantalla en blanco / acceso de solo lectura? ¡Nada!

Sin embargo, si sus sitios permiten contraseñas débiles, hay algunos problemas . Pero es la política de sus sitios, REST API no sabe nada de eso.

  

¿Es posible permitir que solo usuarios autorizados accedan a un punto final?

¡Sí! Puede hacerlo utilizando devolución de llamada de permiso .

Ejemplo de usuarios 'devolución de llamada de verificación de permisos :

if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
    return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you cannot view this resource with edit context.' ), array( 'status' => rest_authorization_required_code() ) );
}
  

¿Cómo suelen otras personas configurar estos datos para que puedan acceder a las aplicaciones externas sin exponer demasiada información?

Esta pregunta es difícil de responder porque no sabemos qué / cuándo es demasiada información . Pero todos estamos usando referencias y cheatsheets .

    
respondido por el MinhTri 03.06.2016 - 07:08
5
  

¿Es posible permitir que solo usuarios autorizados accedan a un punto final?

Es posible agregar una devolución de llamada de permiso personalizada a su punto final de API que requiere autenticación para ver el contenido. Los usuarios no autorizados recibirán una respuesta de error "code": "rest_forbidden"

La forma más sencilla de hacer esto es extender WP_REST_Posts_Controller. Aquí hay un ejemplo muy simple de eso:

class My_Private_Posts_Controller extends WP_REST_Posts_Controller {

   /**
   * The namespace.
   *
   * @var string
   */
   protected $namespace;

   /**
   * The post type for the current object.
   *
   * @var string
   */
   protected $post_type;

   /**
   * Rest base for the current object.
   *
   * @var string
   */
   protected $rest_base;

  /**
   * Register the routes for the objects of the controller.
   * Nearly the same as WP_REST_Posts_Controller::register_routes(), but with a 
   * custom permission callback.
   */
  public function register_routes() {
    register_rest_route( $this->namespace, '/' . $this->rest_base, array(
        array(
            'methods'             => WP_REST_Server::READABLE,
            'callback'            => array( $this, 'get_items' ),
            'permission_callback' => array( $this, 'get_items_permissions_check' ),
            'args'                => $this->get_collection_params(),
            'show_in_index'       => true,
        ),
        array(
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => array( $this, 'create_item' ),
            'permission_callback' => array( $this, 'create_item_permissions_check' ),
            'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
            'show_in_index'       => true,
        ),
        'schema' => array( $this, 'get_public_item_schema' ),
    ) );

    register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
        array(
            'methods'             => WP_REST_Server::READABLE,
            'callback'            => array( $this, 'get_item' ),
            'permission_callback' => array( $this, 'get_item_permissions_check' ),
            'args'                => array(
                'context' => $this->get_context_param( array( 'default' => 'view' ) ),
            ),
            'show_in_index'       => true,
        ),
        array(
            'methods'             => WP_REST_Server::EDITABLE,
            'callback'            => array( $this, 'update_item' ),
            'permission_callback' => array( $this, 'update_item_permissions_check' ),
            'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
            'show_in_index'       => true,
        ),
        array(
            'methods'             => WP_REST_Server::DELETABLE,
            'callback'            => array( $this, 'delete_item' ),
            'permission_callback' => array( $this, 'delete_item_permissions_check' ),
            'args'                => array(
                'force' => array(
                    'default'     => true,
                    'description' => __( 'Whether to bypass trash and force deletion.' ),
                ),
            ),
            'show_in_index'       => false,
        ),
        'schema' => array( $this, 'get_public_item_schema' ),
    ) );     
  }

  /**
   * 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 get_items_permissions_check( $request ) {
    return current_user_can( 'edit_posts' );
  }

}

Notarás que la devolución de llamada de permisos function get_items_permissions_check usa current_user_can para determinar si se debe permitir el acceso. Dependiendo de cómo esté usando la API, es posible que necesite aprender más sobre la autenticación del cliente.

Luego puede registrar su tipo de publicación personalizada con el soporte de la API REST agregando los siguientes argumentos en register_post_type

  /**
   * Register a book post type, with REST API support
   *
   * Based on example at: http://codex.wordpress.org/Function_Reference/register_post_type
   */
  add_action( 'init', 'my_book_cpt' );
  function my_book_cpt() {
    $labels = array(
        'name'               => _x( 'Books', 'post type general name', 'your-plugin-textdomain' ),
        'singular_name'      => _x( 'Book', 'post type singular name', 'your-plugin-textdomain' ),
        'menu_name'          => _x( 'Books', 'admin menu', 'your-plugin-textdomain' ),
        'name_admin_bar'     => _x( 'Book', 'add new on admin bar', 'your-plugin-textdomain' ),
        'add_new'            => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
        'add_new_item'       => __( 'Add New Book', 'your-plugin-textdomain' ),
        'new_item'           => __( 'New Book', 'your-plugin-textdomain' ),
        'edit_item'          => __( 'Edit Book', 'your-plugin-textdomain' ),
        'view_item'          => __( 'View Book', 'your-plugin-textdomain' ),
        'all_items'          => __( 'All Books', 'your-plugin-textdomain' ),
        'search_items'       => __( 'Search Books', 'your-plugin-textdomain' ),
        'parent_item_colon'  => __( 'Parent Books:', 'your-plugin-textdomain' ),
        'not_found'          => __( 'No books found.', 'your-plugin-textdomain' ),
        'not_found_in_trash' => __( 'No books found in Trash.', 'your-plugin-textdomain' )
    );

    $args = array(
        'labels'             => $labels,
        'description'        => __( 'Description.', 'your-plugin-textdomain' ),
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => array( 'slug' => 'book' ),
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => null,
        'show_in_rest'       => true,
        'rest_base'          => 'books-api',
        'rest_controller_class' => 'My_Private_Posts_Controller',
        'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
    );

    register_post_type( 'book', $args );
}

Verás que rest_controller_class usa My_Private_Posts_Controller en lugar del controlador predeterminado.

Me ha resultado difícil encontrar buenos ejemplos y explicaciones para usar la API REST fuera de la documentación . Encontré esta gran explicación de la extensión del controlador predeterminado , y aquí hay guía muy completa para agregar puntos finales .

    
respondido por el Dalton 19.07.2016 - 19:49
1

Esto es lo que he usado para evitar que todos los usuarios que no han iniciado sesión utilicen la API REST:

add_filter( 'rest_api_init', 'rest_only_for_authorized_users', 99 );
function rest_only_for_authorized_users($wp_rest_server){
    if ( !is_user_logged_in() ) {
        wp_die('sorry you are not allowed to access this data','cheatin eh?',403);
    }
}
    
respondido por el squarecandy 01.12.2017 - 03:48
0
add_filter( 'rest_api_init', 'rest_only_for_authorized_users', 99 );
function rest_only_for_authorized_users($wp_rest_server)
{
if( !is_user_logged_in() ) 

    wp_die('sorry you are not allowed to access this data','Require Authentication',403);
} } 
function json_authenticate_handler( $user ) {

global $wp_json_basic_auth_error;

$wp_json_basic_auth_error = null;

// Don't authenticate twice
if ( ! empty( $user ) ) {
    return $user;
}

if ( !isset( $_SERVER['PHP_AUTH_USER'] ) ) {
    return $user;
}

$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];


remove_filter( 'determine_current_user', 'json_authenticate_handler', 20 );

$user = wp_authenticate( $username, $password );

add_filter( 'determine_current_user', 'json_authenticate_handler', 20 );

if ( is_wp_error( $user ) ) {
    $wp_json_basic_auth_error = $user;
    return null;
}

$wp_json_basic_auth_error = true;

return $user->ID;}add_filter( 'determine_current_user', 'json_authenticate_handler', 20 );
    
respondido por el dipen patel 08.01.2018 - 12:56

Lea otras preguntas en las etiquetas