En este post te mostraré cómo autenticar un usuario existente de WordPress desde un lugar externo; es decir, desde otro sistema, software, código o como le quieras llamar.
Dicho con otras palabras, te mostraré cómo hacer un login externo usando el usuario y contraseña de los usuarios de WordPress.
Por ejemplo, yo tengo un sistema en el que quiero autenticar a los usuarios con los que ya tengo en mi WordPress, así que quiero reutilizar esa tabla de usuarios y verificar si la contraseña y usuario coinciden, sin usar las funciones de WordPress.
Requisitos para leer base de datos de WordPress

Esto lo vamos a hacer con PHP, pero técnicamente hablando se podría hacer desde cualquier lenguaje de programación que pueda conectarse a MySQL y usar el algoritmo de hasheo de WP.
Para que funcione con PHP, el programa debe estar en el mismo servidor que el sitio de WordPress, y si no, al menos la base de datos debe estar disponible de manera remota.
Comprobar contraseña de WordPress
Esto es como hacer un login simple, lo que va a cambiar será el modo de comprobar si la contraseña es correcta, pues vamos a usar PasswordHash: Portable PHP password hashing framework.
Puedes descargarlo desde la página oficial, e incluirlo como mejor lo prefieras.
Obteniendo base de datos
En este caso usaré PDO para obtener una conexión a la base de datos. Recuerda cambiar las credenciales como sea necesario.
<?php
function obtenerBaseDeDatosWordPress()
{
$pass = "";
$usuario = "root";
$nombreBaseDeDatos = "wp";
$baseDeDatos = new PDO('mysql:host=localhost;dbname=' . $nombreBaseDeDatos, $usuario, $pass);
$baseDeDatos->query("set names utf8;");
$baseDeDatos->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
$baseDeDatos->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$baseDeDatos->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
return $baseDeDatos;
}
Como puedes ver es una simple conexión a la base de datos de MySQL de WordPress en donde están almacenados los usuarios.
Obtener usuario de WordPress
Ahora que tenemos la conexión, vamos a leer los datos. Los usuarios están en wp_users
(me parece que puede cambiar si cambiaste el prefijo de las tablas, así que podría ser simplemente users
) y sus roles (administrador, suscriptor, colaborador) están en wp_usermeta
por lo que la consulta y la función quedan así:
<?php
function obtenerUsuarioDeWordPress($usuarioOCorreo)
{
$bd = obtenerBaseDeDatosWordPress();
$sentencia = $bd->prepare("SELECT * FROM wp_users
INNER JOIN wp_usermeta ON wp_users.ID = wp_usermeta.user_id
WHERE (wp_users.user_login = ? OR wp_users.user_email = ?) AND wp_usermeta.meta_key = ?");
$sentencia->execute([$usuarioOCorreo, $usuarioOCorreo, "wp_capabilities"]);
return $sentencia->fetchObject();
}
En este caso el usuario puede autenticarse con el correo o con el nombre de usuario. La función regresará un objeto de usuario que tendrá todos los datos del mismo.
Aquí hay algo muy importante y es que el rol está dentro de meta_value
pero este valor está serializado así que debemos usar unserialize
y hacer un montón de comprobaciones para saber el rol.
Autenticar usuario
Ahora que ya tenemos esa función, veamos cómo autenticar. Lo que hacemos es:
- Obtener el usuario de la base de datos de WordPress
- Incluir a PasswordHash para comprobar la contraseña
- Si todo es correcto, volvemos a regresar al usuario, con el rol ya arreglado
- Si algo falla (la contraseña no es correcta, no existe el usuario, etcétera) regresamos
false
Entonces queda así:
<?php
function autenticarUsuario($username, $password)
{
# Obtener usuario. Si no existe, regresamos false inmediatamente
$usuario = obtenerUsuarioDeWordPress($username);
if (!$usuario) return false;
# Incluimos PasswordHash pues vamos a realizar algunas comprobaciones
include_once "PasswordHash.php";
# Esta es la contraseña almacenada en la base de datos:
$storedHash = $usuario->user_pass;
# Crear instancia de PasswordHash
$passwordHash = new PasswordHash(8, false);
$metaValue = unserialize($usuario->meta_value);
# Nota: en mi caso solo permito usuarios administradores y colaboradores; ignoro a los demás.
# Si tú quieres permitirlos, modifica el código
if (!isset($metaValue["administrator"]) && !isset($metaValue["contributor"])) {
return false;
}
if ((isset($metaValue["administrator"]) && !$metaValue["administrator"]) && (isset($metaValue["contributor"]) && !$metaValue["contributor"])) {
return false;
}
# Ahora sí comprobamos la contraseña plana ($password) con la hasheada almacenada ($storedHash)
if ($passwordHash->CheckPassword($password, $storedHash)) {
# Si llegamos aquí, el usuario y contraseña son correctos
# Lo único que hacemos es poner el rol del mismo
if ((isset($metaValue["administrator"])) && $metaValue["administrator"]) {
$usuario->role = "administrator";
} else if (isset($metaValue["contributor"]) && $metaValue["contributor"]) {
$usuario->role = "contributor";
}
# Y regresamos el usuario
return $usuario;
} else {
# Caso contrario (la contraseña no coincide) regresamos igualmente false
return false;
}
}
La función recibe el nombre de usuario o correo, y la contraseña plana. Obtiene el usuario, comprueba los datos y en caso de que todo vaya bien, regresará el usuario.
Si la contraseña no coincide o el usuario no existe, regresa false
. A partir de la llamada de esta función podríamos iniciar sesión, pues si nos regresa un usuario podemos iniciar y establecer datos en la sesión.
A continuación te mostraré un ejemplo de uso de la función.
Poniendo todo junto
También he grabado un vídeo explicando el código, te invito a verlo y a que te suscribas:
Veamos el ejemplo completo, a continuación el código. Recuerda que la clase PasswordHash.php debe estar en el mismo directorio que este código.
<?php
/*
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me /
------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Creado por Parzibyte (https://parzibyte.me). Este encabezado debe mantenerse intacto,
excepto si este es un proyecto de un estudiante.
*/
function obtenerBaseDeDatosWordPress()
{
$pass = "";
$usuario = "root";
$nombreBaseDeDatos = "wp";
$baseDeDatos = new PDO('mysql:host=localhost;dbname=' . $nombreBaseDeDatos, $usuario, $pass);
$baseDeDatos->query("set names utf8;");
$baseDeDatos->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
$baseDeDatos->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$baseDeDatos->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
return $baseDeDatos;
}
function obtenerUsuarioDeWordPress($usuarioOCorreo)
{
$bd = obtenerBaseDeDatosWordPress();
$sentencia = $bd->prepare("SELECT * FROM wp_users
INNER JOIN wp_usermeta ON wp_users.ID = wp_usermeta.user_id
WHERE (wp_users.user_login = ? OR wp_users.user_email = ?) AND wp_usermeta.meta_key = ?");
$sentencia->execute([$usuarioOCorreo, $usuarioOCorreo, "wp_capabilities"]);
return $sentencia->fetchObject();
}
function autenticarUsuario($username, $password)
{
# Obtener usuario. Si no existe, regresamos false inmediatamente
$usuario = obtenerUsuarioDeWordPress($username);
if (!$usuario) return false;
# Incluimos PasswordHash pues vamos a realizar algunas comprobaciones
include_once "PasswordHash.php";
# Esta es la contraseña almacenada en la base de datos:
$storedHash = $usuario->user_pass;
# Crear instancia de PasswordHash
$passwordHash = new PasswordHash(8, false);
$metaValue = unserialize($usuario->meta_value);
# Nota: en mi caso solo permito usuarios administradores y colaboradores; ignoro a los demás.
# Si tú quieres permitirlos, modifica el código
if (!isset($metaValue["administrator"]) && !isset($metaValue["contributor"])) {
return false;
}
if ((isset($metaValue["administrator"]) && !$metaValue["administrator"]) && (isset($metaValue["contributor"]) && !$metaValue["contributor"])) {
return false;
}
# Ahora sí comprobamos la contraseña plana ($password) con la hasheada almacenada ($storedHash)
if ($passwordHash->CheckPassword($password, $storedHash)) {
# Si llegamos aquí, el usuario y contraseña son correctos
# Lo único que hacemos es poner el rol del mismo
if ((isset($metaValue["administrator"])) && $metaValue["administrator"]) {
$usuario->role = "administrator";
} else if (isset($metaValue["contributor"]) && $metaValue["contributor"]) {
$usuario->role = "contributor";
}
# Y regresamos el usuario
return $usuario;
} else {
# Caso contrario (la contraseña no coincide) regresamos igualmente false
return false;
}
}
# Momento de probar. Usaré <pre> para que se vea de mejor manera, pero recuerda que solo estoy depurando ;)
echo "<pre>";
echo "Debería mostrar los datos correctos: ";
$usuarioCorrecto = autenticarUsuario("parzibyte", "hunter2");
echo json_encode($usuarioCorrecto, JSON_PRETTY_PRINT);
echo "\n\nAhora debería mostrar false: ";
$usuarioIncorrecto = autenticarUsuario("inexistente", "blabla");
echo json_encode($usuarioIncorrecto, JSON_PRETTY_PRINT);
echo "</pre>";
Igualmente dejo el código completo en mi GitHub. No olvides cambiar las credenciales de la base de datos. Aquí puedes leer más artículos de WordPress.