Como validar um usuário do ouside wordpress / php?

9

Estou trabalhando em um aplicativo ajax que será incorporado em uma página do wordpress. O aplicativo ajax troca dados com servlets em execução no tomcat. Agora os servlets precisam de uma maneira de determinar se uma solicitação vem de um usuário que está logado no wordpress. E se o usuário estiver conectado, os servlets também deverão poder determinar o ID do usuário para poder consultar o banco de dados. Se o usuário não estiver logado, a solicitação será negada.

Portanto, em outras palavras, eu preciso permitir que um servlet execute uma solicitação apenas se o usuário que causou a solicitação estiver conectado ao wordpress (versão 3.3.x). Tanto o servlet (tomcat) quanto o wordpress (apache2) são executados na mesma máquina física e compartilham o mesmo banco de dados.

Em teoria, isso poderia ser facilmente resolvido fazendo o seguinte:

  1. Durante o logon do wordpress, algum token do usuário é armazenado em uma variável javascript.
  2. O aplicativo ajax encaminha o token do usuário para os servlets em todas as chamadas.
  3. Os servlets usam o token para consultar o wordpress se ele é válido (ou seja, se o usuário estiver logado) e executar ou negar a solicitação.

A questão é como isso pode ser implementado no lado do wordpress?
Porque, o que torna a teoria tão complicada é o fato de eu ainda não ter feito nenhuma programação php.

Primeiro, eu estava pensando em transmitir o cookie wordpress_logged_in (auth) ao servlet e deixar o servlet consultar o wordpress se o cookie de autenticação ainda é válido. Mas, ao que parece, isso não pode ser feito, pois wp_validate_auth_cookie () sempre falha, mesmo que os dados de cookie de um usuário conectado sejam passados. Uma outra solução poderia ser desenvolver um plug-in que armazene o ID da sessão e o ID do usuário em uma tabela, que poderia ser facilmente consultada pelos servlets. Ou talvez haja outra solução ...

Davos Seaworth
fonte
Por que não escrever ou usar um plug-in que ofereça autenticação de usuário como serviço AJAX? Ele poderia usar a pilha WP inteira e qualquer aplicativo poderia usá-lo emitindo uma solicitação HTTP adequada. Porém, tome cuidado para proteger as credenciais do usuário adequadamente.
Raphael
Acho que me expressei errado, não preciso de um serviço de autenticação ajax. O que eu preciso é uma maneira de permitir que um servlet valide um usuário já autenticado. Ou seja, verifique se o usuário ainda está conectado. A questão é a seguinte: o usuário efetua login, acessa um aplicativo ajax, que se comunica com o servlet para armazenar / recuperar dados. Agora, o servlet precisa de uma maneira de 1) testar se a solicitação vem de um usuário conectado e 2) recuperar o ID do usuário (para acesso adicional ao banco de dados).
Davos Seaworth
Talvez você deva editar sua pergunta para incorporar todos esses comentários. De preferência, apresente seu problema (!) E qual é sua ideia. Em particular, forneça uma descrição passo a passo clara do processo que você imagina.
Raphael
Espero que a pergunta esteja mais clara agora.
Davos Seaworth
como você acabou fazendo isso? você poderia compartilhar sua solução? você usou XMLRPC?
Pkeck #

Respostas:

7

O WordPress já possui uma API incorporada por meio de um servidor XMLRPC. Ou seja, você pode fazer uma solicitação XMLRPC a partir do seu aplicativo java e verificar um nome de usuário / senha. Infelizmente, não há como se autenticar como está.

Dito isto, é muito fácil criar o seu próprio. Basta conectar xmlrpc_methodsum filtro e adicionar o seu. A chave da matriz que você adiciona é o método xmlrpc que você chama do seu aplicativo e o valor será a função que é chamada pelo servidor XMLRPC do 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;
}

E a função de retorno de chamada wpse39662_check_loginreceberia um argumento, a matriz de itens enviados ao 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;
}

Aqui está tudo isso como um plugin . Com isso instalado e o XMLRPC ativado em seu site WP, você poderá fazer solicitações com algum cliente XMLRPC (tenho certeza que o Java possui um).

Aqui está o código que usei para testar o acima (cliente Python XMLRPC).

>>> import xmlrpclib as xmlrpc
>>> s = xmlrpc.ServerProxy('http://wordpress.dev/xmlrpc.php')
>>> s.wpse39662.login('admin', 'password')
True
chrisguitarguy
fonte
11
Obrigado! Isso me traz um grande passo adiante! O mesmo pode ser alcançado usando o cookie de autenticação do usuário? Então eu não tenho que armazenar e enviar o nome de usuário / pwd pelo fio? Meu projeto consiste em um aplicativo ajax incorporado a uma página do wordpress. O aplicativo ajax chama um servlet e o servlet pergunta ao wordpress se o usuário está autenticado. Eu poderia passar o usuário / pwd para o aplicativo ajax e transferi-lo para o servlet, mas temo que isso não seja muito seguro. Tentei passar o conteúdo do cookie de autenticação para wp_validate_auth_cookie (), mas ele sempre falha.
Davos Seaworth
Gostaria apenas de gerar um token ou algo para o usuário e armazená-lo nas duas extremidades do sistema. Depois, passe o token para frente e para trás.
Chrisguitarguy
2

O Wordpress (atualmente) verifica se o usuário ainda está logado, verificando um dos cookies que ele fornece no login. Ele constrói o conteúdo desse cookie fazendo um hash. Os detalhes estão na função "wp_generate_auth_cookie" em /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);
}

Você pode recriar esse algoritmo (usando essa e outras funções auth_cookie) em seu código Java para fazer as mesmas verificações. O JS pode ser usado para garantir que o cookie seja enviado ao seu servlet.

Caso contrário, XMLRPC pode ser uma boa ideia. Você pode escrever um novo método (como explicado em outra solução aqui) para validar o cookie de autenticação (em vez de validar o nome de usuário e a senha como normalmente é feito).

rindobovino
fonte
2

Obtenha o plug-in Exec-PHP e faça uma página do WordPress (não uma postagem) com um bom link permanente ( http://mysite/user_id/) e o código na get_current_user_id()referência da 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.'.';
}
?>

Você pode então extrair os cookies que o cliente envia e colocá-los em uma GETsolicitação http://127.0.0.1/user_id/. Então você saberá se o usuário está logado e qual é o seu ID de usuário.

Olathe
fonte
1

Você pode fazer algo assim nas páginas não-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
}

?>
FlashingCursor
fonte
Obrigado pela resposta, o problema é que os servlets são escritos em java, portanto o código php não pode ser executado. O que estou procurando é algum tipo de interface externa que permita que um servlet / java se comunique com o wordpress / php. Há certamente algum tipo de interface disponível, eu sou apenas incapaz de encontrá-lo ...
Davos Seaworth
Ah entendo. Talvez usar algo como Quercus caucho.com/resin-3.0/quercus possa lhe proporcionar o melhor dos dois mundos?
FlashingCursor
Obrigado, mas o quercus é a solução errada, pois eu já tenho um wordpress / php / apache em funcionamento e uma instalação de servlet / java / tomcat em funcionamento. Agora, a única coisa de que preciso é de uma interface entre esses dois, que permita ao servlet verificar se um usuário está logado no wordpress (alguma interface / protocoll / ipc / o que for).
Davos Seaworth
1

Este é um plug-in WordPress de um arquivo que faz o trabalho:

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');

Ele basicamente expõe um novo método XML-RPC com o qual você pode solicitar ao WordPress para validar o wordpress_logged_in_...cookie.

Você precisa escrever algum código para consultar esse método e transmitir o valor do wordpress_logged_in_...cookie.

Este método retornará false(se o cookie não validar) ou o ID do usuário se a validação for bem-sucedida.

kYuZz
fonte