
Cuando un suscriptor inicia sesión en WordPress, aterriza por defecto en el escritorio de administración, una pantalla que no tiene ningún sentido para alguien que solo va a leer contenido premium o gestionar su cuenta. Redirigirlo automáticamente a la página correcta según su rol mejora la experiencia de usuario y evita que vea partes del backend que no le corresponden.
El hook que hay que usar es login_redirect, no admin_init como se usaba en los snippets de 2012. El hook admin_init se ejecuta en cada carga del escritorio, no solo después del login, lo que causa redirecciones inesperadas. login_redirect se ejecuta exactamente en el momento del login y recibe la URL de redirección por defecto, el objeto del usuario y la URL solicitada.
Este snippet cubre los roles estándar de WordPress (administrator, editor, author, subscriber) y el rol customer de WooCommerce. Usa current_user_can() en lugar de comparar el nombre del rol directamente, lo que es más robusto si tienes roles personalizados que heredan capacidades.
/**
* Redirige a los usuarios a una URL específica según su rol después del login.
* Hook: login_redirect
*
* @param string $redirect_to URL de redirección por defecto.
* @param string $requested_redirect_to URL solicitada antes del login (si la hay).
* @param WP_User $user Objeto del usuario logueado.
* @return string URL de destino.
*/
function wpdirecto_redirect_after_login( $redirect_to, $requested_redirect_to, $user ) {
// Si hay un error en el login, devolver la URL por defecto.
if ( is_wp_error( $user ) ) {
return $redirect_to;
}
// Si el usuario ya tenía una URL de destino explícita y es del mismo sitio,
// respetarla (evita open redirect).
if ( ! empty( $requested_redirect_to ) && wp_validate_redirect( $requested_redirect_to ) ) {
return $requested_redirect_to;
}
// Administrador: al escritorio de WordPress.
if ( $user->has_cap( 'manage_options' ) ) {
return admin_url();
}
// Editor: al listado de entradas.
if ( $user->has_cap( 'edit_others_posts' ) ) {
return admin_url( 'edit.php' );
}
// Autor: a sus propias entradas.
if ( $user->has_cap( 'publish_posts' ) ) {
return admin_url( 'edit.php?author=' . $user->ID );
}
// Customer de WooCommerce: a la página Mi cuenta.
if ( $user->has_cap( 'read' ) && class_exists( 'WooCommerce' ) ) {
$myaccount_page = get_option( 'woocommerce_myaccount_page_id' );
if ( $myaccount_page ) {
return get_permalink( $myaccount_page );
}
}
// Suscriptor y otros roles sin capacidades especiales: a la portada.
return home_url( '/' );
}
add_filter( 'login_redirect', 'wpdirecto_redirect_after_login', 10, 3 );Lenguaje del código: PHP (php)
Puedes añadir este código al fichero functions.php de tu tema hijo, o mejor aún, en un plugin de un fichero propio para que no se pierda si cambias de tema. Si quieres aplicarlo con mayor seguridad sin depender del tema, usa un mu-plugin (must-use plugin) en la carpeta wp-content/mu-plugins/.
Los mu-plugins se cargan antes que los plugins normales y no se pueden desactivar desde el panel. Crea el fichero wp-content/mu-plugins/redirect-by-role.php con este contenido:
<?php
/**
* Plugin Name: Redirect by Role After Login
* Description: Redirige usuarios al destino correcto según su rol de WordPress.
*/
if ( ! defined( 'ABSPATH' ) ) exit;
add_filter( 'login_redirect', function( $redirect_to, $requested_redirect_to, $user ) {
if ( is_wp_error( $user ) ) return $redirect_to;
if ( ! empty( $requested_redirect_to ) && wp_validate_redirect( $requested_redirect_to ) ) {
return $requested_redirect_to;
}
if ( $user->has_cap( 'manage_options' ) ) return admin_url();
if ( $user->has_cap( 'edit_others_posts' ) ) return admin_url( 'edit.php' );
if ( $user->has_cap( 'publish_posts' ) ) return admin_url( 'edit.php?author=' . $user->ID );
return home_url( '/' );
}, 10, 3 );Lenguaje del código: HTML, XML (xml)
Un open redirect ocurre cuando tu sitio redirige a una URL externa sin validarla. Si alguien envía a tus usuarios un enlace del tipo tudominio.com/wp-login.php?redirect_to=https://sitiomalicioso.com y el código no valida que la URL de destino pertenece a tu dominio, el atacante puede usarlo para phishing.
El snippet anterior usa wp_validate_redirect() que, por defecto, solo permite redirecciones al mismo dominio. No construyas URLs de redirección con datos directos de $_GET o $_POST sin pasar por esta función.
Si también trabajas con WooCommerce, puede interesarte ver la lista de plugins imprescindibles para WooCommerce, algunos de los cuales incluyen gestión avanzada de cuentas de cliente. Para la seguridad general del login, consulta nuestra guía de mejores prácticas de seguridad en WordPress. Y si necesitas gestionar otras personalizaciones de comportamiento del sitio, el artículo sobre trucos en functions.php puede serte útil.
El hook admin_init se ejecuta en cada visita al escritorio de WordPress, no solo al hacer login. Usarlo para redirecciones provoca comportamientos inesperados: el usuario es redirigido cada vez que intenta acceder al admin, no solo al autenticarse. El hook login_redirect se ejecuta exclusivamente en el proceso de autenticación.
Sí, puedes usar in_array('administrator', $user->roles), pero no es lo recomendado. Si tienes roles personalizados que heredan capacidades de administrador, este método los ignoraría. Usar has_cap('manage_options') es más robusto porque comprueba la capacidad real, independientemente del nombre del rol.
Puedes usar user meta para marcar el primer login: en el hook login_redirect, comprueba si el meta _first_login_done existe para ese usuario. Si no existe, redirige a la página de bienvenida y guarda el meta con update_user_meta(). En visitas posteriores el meta ya estará y la redirección especial no se ejecutará.
Sí. El snippet incluye una rama específica para el rol customer de WooCommerce que redirige a la página de Mi Cuenta configurada en WooCommerce. La condición class_exists('WooCommerce') evita errores si WooCommerce no está instalado.
Sí. Usa wp_validate_redirect() antes de respetar una URL de redirección externa, lo que garantiza que solo se permiten redirecciones al mismo dominio. Las URLs externas son ignoradas y el usuario va a la URL asignada por rol.
