¿Cómo validar a un usuario desde fuera de wordpress / php?

9

Estoy trabajando en una aplicación ajax que se incrustará en una página de wordpress. La aplicación ajax intercambia datos con servlets que se ejecutan en tomcat. Ahora los servlets necesitan una forma de determinar si una solicitud proviene de un usuario que ha iniciado sesión en WordPress. Y si el usuario ha iniciado sesión, los servlets también deben poder determinar la identificación de los usuarios para poder consultar la base de datos. Si el usuario no está registrado, la solicitud será denegada.

En otras palabras, necesito dejar que un servlet realice una solicitud solo si el usuario que causó la solicitud ha iniciado sesión en wordpress (versión 3.3.x). Tanto el servlet (tomcat) como wordpress (apache2) se ejecutan en la misma máquina física y comparten la misma base de datos.

En teoría, esto podría resolverse fácilmente haciendo lo siguiente:

  1. Durante el inicio de sesión de WordPress, algunos tokens de usuario se almacenan en una variable de JavaScript.
  2. La aplicación ajax reenvía el token de usuario a los servlets en cada llamada.
  3. Los servlets usan el token para consultar wordpress si es válido (es decir, si el usuario ha iniciado sesión) y realizar o rechazar la solicitud.

La pregunta es cómo se puede implementar esto en el lado de WordPress.
Porque, lo que hace que la teoría sea tan complicada es el hecho de que todavía no he hecho ninguna programación php.

Primero estaba pensando en transmitir la cookie wordpress_logged_in (auth) al servlet y dejar que el servlet consulte wordpress si la cookie de autenticación sigue siendo válida. Pero como parece, esto no se puede hacer, ya que wp_validate_auth_cookie () siempre falla, incluso si se pasan los datos de cookies de un usuario conectado. Otra solución podría ser desarrollar un complemento que almacene el ID de sesión y el ID de usuario en una tabla, que los servlets podrían consultar fácilmente. O tal vez hay otra solución ...

Davos Seaworth
fuente
¿Por qué no escribir o usar un complemento que ofrezca autenticación de usuario como servicio AJAX? Podría usar toda la pila de WP, y cualquier aplicación podría usarla emitiendo una solicitud HTTP adecuada. Sin embargo, tenga cuidado de proteger las credenciales de su usuario de manera adecuada.
Raphael
Creo que me expresé mal, no necesito un servicio de autenticación ajax. Lo que necesito es una forma de permitir que un servlet valide a un usuario ya autenticado. Es decir, verificar si el usuario todavía está conectado. El punto es este: el usuario inicia sesión, accede a una aplicación ajax, que se comunica con el servlet para almacenar / recuperar datos. Ahora el servlet necesita alguna forma de 1) probar si la solicitud proviene de un usuario conectado y 2) recuperar la identificación de los usuarios (para un mayor acceso a la base de datos).
Davos Seaworth
Tal vez deberías editar tu pregunta para incorporar todos esos comentarios. Preferiblemente, presente su problema (!) Y cuál es su idea. En particular, brinde una descripción clara paso a paso del proceso que visualiza.
Raphael
Espero que la pregunta sea más clara ahora.
Davos Seaworth
¿Cómo terminaste haciéndolo? ¿podrías compartir tu solución? ¿Usaste XMLRPC?
pkyeck

Respuestas:

7

WordPress ya tiene una API integrada a través de un servidor XMLRPC. Es decir, puede realizar una solicitud XMLRPC desde su aplicación Java y verificar un nombre de usuario / contraseña. Desafortunadamente, no hay forma de autenticarse a través de él tal como está.

Dicho esto, es muy fácil rodar el tuyo. Simplemente enganche xmlrpc_methodsun filtro y agregue el suyo. La clave de matriz que agregue será el método xmlrpc que llame desde su aplicación, y el valor será la función que llama el servidor XMLRPC de WordPress.

<?php
add_filter('xmlrpc_methods', 'wpse39662_add_login_method' );
/**
 * Filters the XMLRPC methods to allow just checking the login/pass of
 * a given users
 */
function wpse39662_add_login_method( $methods )
{
    $methods['wpse39662.login'] = 'wpse39662_check_login';
    return $methods;
}

Y la función de devolución de llamada wpse39662_check_login, le pasaría un argumento, la matriz de cosas enviadas al servidor XMLRPC.

<?php
function wpse39662_check_login( $args )
{
    $username = $args[0];
    $password = $args[1];

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

    if( is_wp_error( $user ) )
    {
        return false;
    }
    return true;
}

Aquí está todo eso como un complemento . Con eso instalado y XMLRPC habilitado en su sitio WP, debería poder hacer solicitudes con algún cliente XMLRPC (estoy seguro de que Java tiene uno).

Aquí está el código que usé para probar lo anterior (cliente Python XMLRPC).

>>> import xmlrpclib as xmlrpc
>>> s = xmlrpc.ServerProxy('http://wordpress.dev/xmlrpc.php')
>>> s.wpse39662.login('admin', 'password')
True
chrisguitarguy
fuente
1
¡Gracias! ¡Esto me lleva un gran paso más allá! ¿Se puede lograr lo mismo utilizando la cookie de autenticación de usuarios? ¿Entonces no tengo que almacenar y enviar el nombre de usuario / pwd por cable? Mi proyecto consiste en una aplicación ajax que está incrustada en una página de wordpress. La aplicación ajax llama a un servlet y el servlet le pregunta a wordpress si el usuario está autenticado. Podría pasar el usuario / pwd a la aplicación ajax y transferirlo al servlet, pero me temo que no sería muy seguro. Así que intenté pasar el contenido de la cookie de autenticación a wp_validate_auth_cookie () pero siempre falla.
Davos Seaworth
Simplemente generaría un token o algo para el usuario y lo almacenaría en ambos extremos del sistema. Luego pase la ficha de un lado a otro.
chrisguitarguy
2

Wordpress (actualmente) verifica si el usuario aún está conectado al verificar una de las cookies que entrega al iniciar sesión. Construye el contenido de esta cookie haciendo algo de hashing. Los detalles se encuentran en la función "wp_generate_auth_cookie" en /wp-includes/pluggable.php:

function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') {
    $user = get_userdata($user_id);

    $pass_frag = substr($user->user_pass, 8, 4);

    $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme);
    $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key);

    $cookie = $user->user_login . '|' . $expiration . '|' . $hash;

    return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme);
}

Puede volver a crear este algoritmo (usando esta y las otras funciones auth_cookie) en su código Java para hacer las mismas verificaciones. JS podría usarse para asegurarse de que la cookie se envíe a su servlet.

De lo contrario, XMLRPC podría ser una buena idea. Podría escribir un nuevo método (como se explica en otra solución aquí) para validar la cookie de autenticación (en lugar de validar el nombre de usuario y la contraseña como se hace generalmente).

riendo
fuente
2

Obtenga el complemento Exec-PHP , y luego cree una página de WordPress (no una publicación) con un buen enlace permanente ( http://mysite/user_id/) y el código en la get_current_user_id()referencia de la API :

<?php
$user_id = get_current_user_id();
if ($user_id == 0) {
    echo 'You are currently not logged in.';
} else {
    echo 'You are logged in as user '.$user_id.'.';
}
?>

Luego puede extraer las cookies que el cliente le envía y ponerlas en una GETsolicitud http://127.0.0.1/user_id/. Entonces sabrá si el usuario ha iniciado sesión y cuál es su ID de usuario.

Olathe
fuente
1

Podrías hacer algo como esto en las páginas que no son de wp:

<?php
require('./wp-blog-header.php');
// Make sure ^ points to the root of your WP installation

if ( is_user_logged_in() ) {
   // Perform your request here
}

?>
IntermitenteCursor
fuente
Gracias por la respuesta, el problema es que los servlets están escritos en Java, por lo que el código php no se puede ejecutar. Lo que estoy buscando es algún tipo de interfaz externa que permita que un servlet / java se comunique con wordpress / php. Ciertamente hay alguna interfaz amable disponible, simplemente no puedo encontrarla ...
Davos Seaworth
Ah, ya veo. ¿Quizás usar algo como Quercus caucho.com/resin-3.0/quercus podría obtener lo mejor de ambos mundos?
FlashingCursor
Gracias, pero quercus es la solución incorrecta, ya que tengo un wordpress / php / apache y una instalación de servlet / java / tomcat en funcionamiento. Ahora, lo único que necesito es una interfaz entre esos dos, que permita al servlet verificar si un usuario ha iniciado sesión en WordPress (alguna interfaz / protocolo / ipc / lo que sea).
Davos Seaworth
1

Este es un complemento de WordPress de un archivo que hace el trabajo:

function yournamespace_validateAuthCookie($cookie, $scheme = 'logged_in') {
    return wp_validate_auth_cookie($cookie, $scheme);
}

function yournamespace_new_xmlrpc_methods($methods) {
    $methods['yournamespace.validateAuthCookie'] = 'yournamespace_validateAuthCookie';
    return $methods;
}
add_filter('xmlrpc_methods', 'yournamespace_new_xmlrpc_methods');

Básicamente expone un nuevo método XML-RPC con el que puede pedirle a WordPress que valide la wordpress_logged_in_...cookie.

Luego debe escribir un código para consultar este método y pasarle el valor de la wordpress_logged_in_...cookie.

Este método devolverá false(si la cookie no se valida) o la ID de usuario si la validación es exitosa.

kYuZz
fuente