Creare un'API per single sign-on con un sito di terze parti

18 lug 2012, 20:42:14
Visualizzazioni: 19.6K
Voti: 13

Il mio sito deve integrarsi con un software di terze parti, che risiederà su un proprio sottodominio ospitato dalla società produttrice. Devo fornire agli sviluppatori terzi un endpoint che possano utilizzare per effettuare chiamate API (al mio sito WordPress) per consentire agli utenti del mio sito di accedere al sottodominio.

L'altro sito deve autenticare gli utenti del mio sito tramite un'API di qualche tipo.

Non sono sicuro da dove iniziare, ma credo che questo problema sia già stato risolto da persone più esperte di me. Grazie in anticipo!

2
Commenti

Che tipo di chiamate API saranno necessarie? Cosa stai cercando di fare? Hai già esaminato il supporto XML-RPC di WP (http://codex.wordpress.org/XML-RPC_Support) ?

anu anu
19 lug 2012 03:17:50

L'altro sito deve verificare/autenticare gli utenti dal mio sito WP.

emersonthis emersonthis
19 lug 2012 16:31:33
Tutte le risposte alla domanda 1
11
16

Problemi di Cross-site Scripting

Non è possibile trasferire i cookie di autenticazione di WP tra domini. Inoltre, non è consigliabile memorizzare password in chiaro per accedere programmaticamente a un'altra installazione di WP. Pertanto, sarà necessario far accedere gli utenti a WordPress e poi verificare il loro stato di accesso tramite un endpoint API dal sito di terze parti. Questo permette a WordPress di gestire tutta l'autenticazione. È piuttosto sicuro poiché un utente dovrà effettivamente accedere al lato WP affinché l'endpoint API fornisca i dati al sito di terze parti.

Creare un Endpoint API

Consulta questo articolo che ho appena scritto qui: http://coderrr.com/create-an-api-endpoint-in-wordpress/

Inoltre, puoi vedere la dimostrazione del codice qui: https://gist.github.com/2982319

Dovrai definire la logica in base alle esigenze della tua applicazione, ma questo ti permetterà di creare un endpoint da cui poter servire qualsiasi cosa dal lato WordPress.

Poiché stai utilizzando WordPress come sito di autenticazione, puoi usare un controllo come is_user_logged_in(). Se l'utente è loggato, restituisci un oggetto utente al sito di terze parti con tutte le informazioni necessarie.

Accesso dal Sito di Terze Parti

Dal sito di terze parti, puoi collegarti alla pagina di login per un'esperienza fluida utilizzando la variabile di query redirect_to. Una volta effettuato l'accesso, l'utente verrà reindirizzato al sito di terze parti.

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

Accessi Remoti

Se devi far accedere gli utenti a WordPress da un sito di terze parti, puoi utilizzare alcune semplici funzioni di WP elencate su questo sito: http://kuttler.eu/code/log-in-a-wordpress-user-programmatically/

Sarà sicuramente necessario utilizzare un segreto condiviso e creare hash basati sul tempo da quel segreto per mantenere tutto sicuro. Ecco come potrebbe apparire:

Il sito di terze parti invia una richiesta con un timestamp e un token generato da un segreto condiviso:

$shared_secret = 'foobar'; //non inviare questo all'endpoint API
$timestamp = time();
$token = md5($shared_secret.$time_stamp);

L'installazione di WordPress riceve la richiesta:

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

if((time() - $timestamp) > 30) # Soglia di 30 secondi
    //fai qualcosa qui - TOKEN scaduto!

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

if($token == $token_to_check)
    //autenticato!
18 lug 2012 21:43:07
Commenti

Abbastanza sicuro che il software di terze parti non abbia nulla a che fare con WP, quindi essenzialmente è un single sign on, ma con WP che funge da provider di autenticazione.

anu anu
19 lug 2012 17:03:02

@anu: Esatto.

emersonthis emersonthis
20 lug 2012 17:52:18

@Brian: Sono interessato all'idea di passare a un'installazione multi-site, ma non capisco appieno il punto che hai sollevato riguardo ai cookie. Tutto ciò che deve accadere è che il software di terze parti deve verificare che il suo utente sia effettivamente uno dei miei utenti. Il software è per il resto autonomo e può fornire i propri cookie o quant'altro.

emersonthis emersonthis
20 lug 2012 17:56:55

@Emerson Ora capisco. Scusa per la confusione. Potresti usare l'idea dell'endpoint che ho creato e utilizzare un token condiviso nei meta dell'utente per l'autenticazione. Restituisci una risposta JSON al servizio di terze parti se l'utente esiste.

Brian Fegter Brian Fegter
20 lug 2012 20:18:20

Grazie Brian, ho guardato più da vicino e penso di iniziare a capire la tua soluzione. Potresti mostrarmi un po' di codice per esemplificare come funzionerebbe il tuo plugin per la mia applicazione? Ho guardato il codice sorgente ma non lo afferro al 100%.

emersonthis emersonthis
21 lug 2012 17:26:00

Per essere più specifico, sono curioso di sapere come riadattare il tuo plugin per il mio scopo. Dovrei cambiare questo: protected $api = 'http://pugme.herokuapp.com/bomb?count='; in protected $api = http://mydomain.com/api/... dato che il mio script controllerà le informazioni nel mio database, anziché un'API di terze parti... ?

emersonthis emersonthis
23 lug 2012 20:15:21

@Emerson In realtà non avresti bisogno di usare la variabile api dato che starai interrogando il database di WP invece di avere un endpoint per un'API di terze parti. Puoi semplicemente rimuoverla. La magia avviene in add_rewrite_rule(); Se hai altre domande, contattami sul mio sito web.

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

Fantastico. Lo farò.

emersonthis emersonthis
23 lug 2012 20:25:19

@Brian grazie mille, questa è un'ottima soluzione! Ho però una domanda. La richiesta dall'app di terze parti all'endpoint deve essere fata lato client? Ho provato localmente: quando faccio la richiesta direttamente nel browser ottengo una risposta corretta "è loggato" dall'endpoint, ma quando la faccio da una pagina PHP non funziona. Immagino di dover richiedere lo stato di login dal browser perché il lato server non è a conoscenza dello stato.

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

Non sono riuscito a far funzionare questo approccio, nonostante diversi giorni di lavoro.

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

Soluzione molto interessante. Potrebbe esserci un problema se le applicazioni sono installate su server diversi e per qualche motivo l'orario di ogni macchina è differente. Suggerirei di usare un counter invece di time() e passarlo con la richiesta. Entrambe le parti mantengono l'ultimo counter passato, e quando l'API riceve una richiesta con un nuovo counter verifica che sia maggiore dell'ultimo. In questo modo un ritardo non può causare problemi.

guyaloni guyaloni
29 dic 2014 13:24:47
Mostra i restanti 6 commenti