Permitir acceso a wp-admin sólo a administradores WordPress
Los perfiles de usuario en WordPress están todos en el área de administración, incluso de aquellos que nada tienen que ver con la administración de la web. A priori no representa ningún peligro de seguridad como algunos pueden sostener, para mi lo más importante es que la experiencia del usuario puede verse truncada.
Por ejemplo, una tienda online puede requerir la creación de una cuenta de usuario desde la que gestionar la información de envío o de facturación. Es mucho mejor que el usuario permanezca en el frontend con una experiencia integrada, no necesita acceder al backend para nada dónde además se encontrará con un aspecto totalmente diferente al de la tienda dónde estaba comprando. Por eso es frecuente que se solicite permitir el acceso al área de administración sólo a determinados usuarios, sobre todo a administradores. Y eso es lo que vamos a ver en este tutorial.
Hay que tener en cuenta que las solicitudes Ajax en WordPress desde el frontend también necesitan acceso al área de administración (wp-admin/admin-ajax.php
) y no deben ser bloqueadas.
Restricción en base a la capacidad manage_options
La capacidad manage_options
(manejo de opciones del sitio) viene por defecto asociada a los usuarios «administrator». Con la función current_user_can()
podemos comprobar si un usuario que está intentando acceder a alguna zona de wp-admin tiene esta capacidad y si no la tiene redirigirlo al frontend.
add_action( 'admin_init', 'admin_area_for_manage_options_only');
function admin_area_for_manage_options_only() {
if( defined('DOING_AJAX') && DOING_AJAX ) {
// Permitir solicitudes a wp-admin/admin-ajax.php
return;
}
if( ! current_user_can( "manage_options" ) ) {
// Redireccionar a la página principal del sitio
// si el usuario no tiene la capacidad "manage_options"
wp_redirect( esc_url_raw( get_site_url() ) );
exit();
}
}
Restricción en base al rol administrator
Para comprobar si el usuario actual es «administrator» se ha de obtener la información sobre los roles asignados y comprobar si entre ellos está el de «administrator»:
add_action( 'admin_init', 'admin_area_for_admins_only');
function admin_area_for_admins_only() {
if( defined('DOING_AJAX') && DOING_AJAX ) {
// Permitir solicitudes a wp-admin/admin-ajax.php
return;
}
$user = wp_get_current_user();
if( empty( $user ) || ! in_array( "administrator", (array) $user->roles ) ) {
// Redireccionar a la página principal del sitio
// si el usuario no tiene el rol "administrator" asignado
wp_redirect( esc_url_raw( get_site_url() ) );
exit();
}
}
Esta fue mi respuesta a un pregunta en WPSE que puedes votar si crees que es buena y de paso me das unos puntillos ;).
En lugar de redirigir al usuario al home de la web puedes querer redirigirlo a otra URL del frontend, por ejemplo, si usas bbPress puedes estar interesado en redirigir al perfil del usuario en bbPress. Sustituye wp_redirect( esc_url_raw( get_site_url() ) )
por:
wp_redirect( esc_url_raw( bbp_user_profile_url( bbp_get_current_user_id() ) ) );
¿Qué método elegir?
En WordPress existen roles y capacidades (capabilities). A cada rol se le asignan unas determinadas capacidades y es frecuente que para referirse a los usuarios con rol «administrator» se recurra a comprobar si el usuario tiene capacidad para manejar las opciones del sitio (manage_options
). Y esto es lo que se hace en muchos tutoriales sobre permitir el acceso a la administración de WordPress sólo a los administradores.
Pero yo no estoy de acuerdo con esos tutoriales. O al menos no como solución para todos los casos. Si bien es cierto que la capacidad manage_options
viene por defecto asignada al rol «administrator», las capacidades de cada rol pueden ser alteradas a través de plugins. Por ejemplo, se podría asignar la capacidad manage_options
al rol «editor», o se podría crear un rol «webmaster» y asignarle también la capacidad manage_options
. Por eso, si se quiere permitir el acceso a la administración sólo a administradores, o a cualquier otro rol o tipo de usuario, debe comprobarse el rol y no una capacidad.
A pesar de todo esto, yo suelo elegir comprobar la capacidad manage_options
en lugar del rol «administrator» aunque pueda parecer contradictorio. ¿Por qué? Sencillamente por que no tiene sentido que un rol tenga capacidad de manage_options
pero no tenga acceso a wp-admin pues es en la administración dónde las funciones asociadas a esa capacidad pueden ser ejecutadas.
current_user_can
. Este uso se debe evitar pues, según la documentación oficial de WordPress, no se garantiza que funcione correctamente. Además, este «fallo» no ha sido aceptado como bug para ser solucionado pues la función current_user_can
no fue diseñada para este fin.Más información
Además de las soluciones expuestas aquí, existen otras opciones para restringir el acceso a wp-admin, por ejemplo proteger con contraseña el directorio wp-admin a través de .htaccess. En este caso la restricción es manejada a nivel de servidor, no por WordPress, y si se hace una solicitud a wp-admin no se ejecuta ni una línea de código sin que se introduzca el usuario y contraseña configurado en el servidor y además se requerirá después la identificación del usuario en WordPress.