Crear una API para inicio de sesión único con un sitio de terceros

18 jul 2012, 20:42:14
Vistas: 19.6K
Votos: 13

Mi sitio necesita integrarse con un software de terceros, que estará alojado en su propio subdominio, hospedado por la compañía del software. Necesito proporcionar a los desarrolladores externos un endpoint que puedan usar para hacer llamadas API (a mi sitio WordPress) con el fin de permitir que los usuarios de mi sitio accedan al subdominio.

El otro sitio necesita autenticar usuarios de mi sitio a través de algún tipo de API.

No estoy seguro por dónde empezar, pero tengo la sensación de que esto ya lo han resuelto personas más inteligentes que yo. ¡Gracias de antemano!

2
Comentarios

¿Qué tipo de llamadas API serán necesarias? ¿Qué estás intentando hacer? ¿Has revisado el soporte de XML-RPC de WordPress (http://codex.wordpress.org/XML-RPC_Support)?

anu anu
19 jul 2012 03:17:50

El otro sitio necesita verificar/autenticar usuarios desde mi sitio de WordPress.

emersonthis emersonthis
19 jul 2012 16:31:33
Todas las respuestas a la pregunta 1
11
16

Problemas de Cross-site Scripting

No puedes transferir cookies de autenticación de WP entre dominios. Tampoco querrás almacenar contraseñas en texto plano para iniciar sesión en otra instalación de WP de forma programática. Por lo tanto, tendrás que hacer que los usuarios inicien sesión en WordPress y luego accedan a su estado de inicio de sesión a través de un punto final de API desde el sitio de terceros. Esto permite que WordPress maneje toda la autenticación. Es bastante seguro, ya que un usuario tendrá que iniciar sesión físicamente en el lado de WP para que el punto final de API sirva los datos al tercero.

Crear un punto final de API

Consulta este artículo que acabo de escribir aquí: http://coderrr.com/create-an-api-endpoint-in-wordpress/

También puedes ver la demostración del código aquí: https://gist.github.com/2982319

Tendrás que determinar la lógica para las necesidades de tu propia aplicación, pero esto te permitirá crear un punto final donde puedas servir cualquier cosa que desees desde el lado de WordPress.

Como estás usando WordPress como el sitio de autenticación, puedes usar una verificación como is_user_logged_in(). Si el usuario ha iniciado sesión, devuelve un objeto de usuario al tercero con cualquier información que necesiten.

Inicio de sesión desde el sitio de terceros

Desde el sitio de terceros, pueden enlazar a tu página de inicio de sesión para una experiencia fluida usando la variable de consulta redirect_to. Una vez iniciada la sesión, los redirigirá de vuelta al sitio de terceros.

http://sub.yourdomain.com/wp-login.php?redirect_to=http%3A%2F%2Fwww.third-party-domain.com

Inicios de sesión remotos

Si necesitas iniciar sesión de usuarios en WordPress desde un sitio de terceros, puedes usar algunas funciones simples de WP enumeradas en este sitio: http://kuttler.eu/code/log-in-a-wordpress-user-programmatically/

Definitivamente necesitarás usar un secreto compartido y crear hashes basados en tiempo a partir de ese secreto para mantener las cosas seguras. Básicamente, así es como se vería:

El tercero envía una solicitud con una marca de tiempo y un token generado por un secreto compartido:

$shared_secret = 'foobar'; //no envíes esto al punto final de API
$timestamp = time();
$token = md5($shared_secret.$time_stamp);

La instalación de WordPress recibe la solicitud:

$shared_secret = 'foobar';
$timestamp = esc_attr($_GET['timestamp']);

if((time() - $timestamp) > 30) # El umbral es de 30 segundos
    //haz algo aquí - ¡TOKEN expirado!

$token = md5($share_secret.$timestamp);
$token_to_check = esc_attr($_GET);

if($token == $token_to_check)
    //¡autenticado!
18 jul 2012 21:43:07
Comentarios

Bastante seguro de que el software de terceros no tiene nada que ver con WP, así que esencialmente es inicio de sesión único, pero con WP actuando como proveedor de autenticación.

anu anu
19 jul 2012 17:03:02

@anu: Eso es correcto.

emersonthis emersonthis
20 jul 2012 17:52:18

@Brian: Me interesa la idea de cambiar a una instalación multisitio, pero no entiendo completamente el punto que mencionaste sobre las cookies. Todo lo que necesita suceder es que el software de terceros verifique que su usuario es realmente uno de mis usuarios. El software por lo demás es autosuficiente y puede proporcionar sus propias cookies o lo que sea.

emersonthis emersonthis
20 jul 2012 17:56:55

@Emerson Ahora entiendo. Disculpa la confusión. Podrías usar la idea del endpoint que creé y utilizar un token compartido en el meta del usuario para la autenticación. Devuelve una respuesta JSON al tercero si el usuario existe.

Brian Fegter Brian Fegter
20 jul 2012 20:18:20

Gracias Brian, revisé con más detalle y creo que estoy empezando a entender tu solución. ¿Podrías mostrarme un poco de código para ejemplificar cómo funcionaría tu plugin para mi aplicación? Miré el código fuente y no lo estoy entendiendo al 100%.

emersonthis emersonthis
21 jul 2012 17:26:00

Para ser un poco más específico, tengo curiosidad sobre cómo reutilizar tu plugin para mi propósito. ¿Debería cambiar esto: protected $api = 'http://pugme.herokuapp.com/bomb?count='; por protected $api = http://mydomain.com/api/... ya que mi script verificará información en mi base de datos, en lugar de una API de terceros...?

emersonthis emersonthis
23 jul 2012 20:15:21

@Emerson Realmente no necesitarías usar la variable api ya que solo estarías consultando la base de datos de WP en lugar de tener un endpoint para una API de terceros. Puedes simplemente eliminar eso. La magia ocurre en add_rewrite_rule(); Si tienes más preguntas, contáctame en mi sitio web.

Brian Fegter Brian Fegter
23 jul 2012 20:19:38

Genial. Así lo haré.

emersonthis emersonthis
23 jul 2012 20:25:19

@Brian ¡muchas gracias, esta es una excelente solución! Sin embargo, tengo una pregunta. ¿La solicitud desde la aplicación de terceros al endpoint necesita hacerse desde el lado del cliente? Lo he probado localmente: cuando hago la solicitud directamente en el navegador obtengo una respuesta correcta de "está conectado" desde el endpoint, pero cuando lo hago desde una página PHP no. Supongo que necesito solicitar el estado de conexión desde el navegador porque el lado del servidor no es consciente del estado.

And Finally And Finally
7 jul 2014 18:49:47

No he podido hacer que este enfoque funcione, después de varios días de trabajo.

And Finally And Finally
15 jul 2014 18:42:09

Solución muy buena. Podría haber un problema si las aplicaciones están instaladas en diferentes servidores y por alguna razón el tiempo de cada máquina es diferente. Sugeriría usar counter en lugar de time() y pasarlo con la solicitud. Ambos lados mantienen el último contador pasado, y cuando la API recibe una solicitud con un nuevo contador, verifica que el nuevo sea mayor que el último. De esta manera, un retraso no puede causar ningún daño.

guyaloni guyaloni
29 dic 2014 13:24:47
Mostrar los 6 comentarios restantes