Come dovrei progettare un servizio web RESTful per utilizzare terze parti (ad esempio Google, Facebook, Twitter) per l'autenticazione?


25

Per il mio lavoro abbiamo un bel servizio web RESTful che abbiamo creato per guidare un paio di siti Web che abbiamo. Fondamentalmente il servizio web ti consente di creare e lavorare con ticket di supporto e il sito Web è responsabile del front-end. Qualsiasi richiesta di servizio web utilizza un'intestazione di autenticazione che utilizziamo per convalidare l'utente e la sua password per ogni chiamata.

Quest'anno stiamo cercando di espandere le nostre opzioni di accesso in modo che gli utenti sul sito Web possano accedere tramite Google, Twitter e Facebook (possibilmente altri). Tuttavia, ho molti problemi a capire come progettare questo in modo che il servizio web possa usare i provider di autenticazione di terze parti per assicurarsi che gli utenti siano chi dicono di essere. Esistono buone pratiche là fuori per come fare questo?

Attualmente stiamo pensando di fare in modo che il sito web gestisca l'autenticazione degli utenti stessi, quindi utilizziamo una nuova chiamata setSessionId che registra la loro sessione corrente con il back-end del servizio web. Ogni richiesta aggiuntiva al servizio web passerà lungo quell'ID sessione e lo convaliderà. Questi sembrano a posto, ma ho la sensazione nella parte posteriore della testa che non ci sto pensando e tutto il mio forum che naviga e legge le specifiche oauth e openid mi confonde di più. Qualche consiglio su come affrontare questo?


niente di veramente sbagliato in ciò che stai suggerendo. trovo più facile guardare il codice di esempio di integrazione openid rispetto alle specifiche oauth e openid attuali ...
spaceman

Quale lingua / piattaforma stai usando? Non è necessario reinventare la ruota, poiché ci sono strutture per aiutarti sostanzialmente. :)
RobM

@Rob Il servizio web è ospitato su Salesforce.com, ma vi si accede tramite un proxy che al momento della stesura è Node.js. Detto questo, sembra che la domanda generale si applicherebbe a tutte le piattaforme. E sì, spero di usare un framework piuttosto che reinventare la ruota, ma non sono sicuro di quale ruota usare.
Ralph Callaway,

@Ralph Sì, la domanda generale è indipendente dalla piattaforma, ma ha implicazioni pratiche, poiché la piattaforma generalmente restringerà un po 'le opzioni del tuo framework. Quindi, hai un'app front-end personalizzata che usa node.js in un repository di dati e servizi web ospitato da salesforce? È necessario archiviare le informazioni utente / identità nel back-end o solo l'autenticazione e l'autorizzazione per le azioni nel front-end?
RobM

@RobM sì, vorremmo archiviare le informazioni utente sul back-end, ad esempio e-mail, nome, cognome, oltre a tutto ciò che è necessario per convalidare le chiamate future dagli utenti del servizio web una volta che sono stati autenticati.
Ralph Callaway,

Risposte:


14

Sembra che ci siano due obiettivi:

  1. Facile da autenticare per gli utenti finali con i loro account social esistenti
  2. Facile per gli sviluppatori che utilizzano il tuo servizio web

Autorizzare le persone a utilizzare le risorse sul tuo sito rende OAuth2 un meccanismo preferito a causa della popolarità e della disponibilità delle librerie client.

1. Facile per gli utenti finali autenticarsi con i loro account social esistenti

L'utente finale visita un sito che utilizza l'API e sceglie di accedere. Vengono inviati alla tua pagina di accesso OAuth. La tua pagina di accesso mostra un normale nome utente e password per gli account gestiti sul tuo sito e una serie di pulsanti social social in cui possono fare clic per accedere tramite un sito come Facebook. Quando l'utente sceglie Facebook, li reindirizza a Facebook per approvare la scelta (avviando il flusso di autorizzazione di Facebook). Quando l'utente finale completa l'accesso su Facebook, viene reindirizzato al tuo sito.

Quando l'utente viene reindirizzato al tuo sito da Facebook, salvi le informazioni dell'utente in un record utente nel tuo database e quindi generi una nuova sessione per quell'utente. Reindirizzi immediatamente l'utente finale al suo sito downstream originale con oauth access_token, completando il flusso oauth originale.

2. Facile per gli sviluppatori che utilizzano il tuo servizio web

Se sei il fornitore dell'autorizzazione, dovresti creare una semplice interfaccia per gli sviluppatori da cui non cambiano ogni volta che aggiungi un nuovo provider di autenticazione a monte che non implementa perfettamente oauth. Questo è il motivo per cui credo che dovresti implementare un sito del provider OAuth2 e quel sito dovrebbe essere un consumatore dei siti di social auth.

Per lo sviluppatore che utilizza la tua bella API di riposo, non saranno a conoscenza dell'interazione di Facebook a meno che tu non scelga di dare loro un suggerimento attraverso il post di acquisizione della sessione (ad esempio).

TL; DR

Fai in modo che i consumatori delle tue API piacciano implementando OAuth2 e nascondendo le complessità dell'autorità sociale. Durante il flusso oauth per i siti a valle, puoi attivare un flusso oauth aggiuntivo con Facebook.

Immagine perché immagine == parole * 1000:

inserisci qui la descrizione dell'immagine

Possiamo chiamare questo oauth2-piggy-back?

Flusso graduale

  1. L'utente finale visita il sito che utilizza l'API
  2. L'utente finale viene inviato al tuo sito per autorizzare o iscriversi (oauth2)
  3. L'utente finale seleziona l'autenticazione sociale, fa clic sul pulsante di accesso di Facebook
  4. Il tuo sito imposta un cookie o imposta statein oauth Facebook per sapere da dove proviene l'utente
  5. Utente finale reindirizzato a Facebook e accetta la connessione al sito di Facebook
  6. Utente finale reindirizzato al tuo sito per completare la procedura di autenticazione di Facebook
  7. Cerchi o crei l'utente nel tuo database
  8. Si crea una nuova sessione sul server
  9. Reindirizzi l'utente al loro sito originale con il token di sessione

5

Come renderlo estensibile

Per prima cosa dovresti notare che tutti questi API usano lo stesso meccanismo per accedere. Tutti usano OAuth per la loro autenticazione. Questo è necessario sfruttare a partire da una libreria OAuth generale. Non utilizzare le proprie librerie per l'autenticazione, queste saranno inutilizzabili per altri provider. Se riesci a capire OAuth2, è abbastanza facile aggiungere altri provider.

Sfortunatamente ne servono due, perché Twitter non ha ancora saltato il carrozzone OAuth2.

OAuth ha bisogno che tu crei un'interfaccia per la parte di autenticazione. I token verranno scambiati da server a server. Crea un punto di ingresso, in grado di gestire tutte le comunicazioni.

Il token deve essere archiviato in una tabella separata dal tuo account, perché possono essere più token e più profili collegati. Alcuni servizi offrono due token, uno di questi è un token di aggiornamento.

Ora si progetta un'interfaccia, che incapsula le altre funzionalità necessarie. Personalmente imposterò un servizio REST separato per questo. In questo modo è possibile estendere facilmente l'autenticazione ad altri luoghi.
Alcuni servizi utilizzano JSON per comunicare, altri vanno per XML, ecc. Per l'utente principale è necessario unificarli tutti. Questo è un processo piuttosto doloroso, ma qui è possibile ricavare alcuni motivi comuni.

Un altro problema qui è che non tutti i servizi offrono la stessa funzionalità. Ciò può significare che i tuoi servizi non possono fornire l'API completa come specificato. È necessario disporre di una strategia qui, che consente il downgrade grazioso dell'applicazione.

Tutto ciò garantirà la possibilità di aggiungere facilmente nuovi fornitori di terze parti.

Problemi di token

I token sono limitati nel tempo, quindi è necessario un paio di processi cron, che possono verificare se il token è ancora utilizzabile, altrimenti è necessario eliminarlo. Puoi anche aggiornare un token con questo meccanismo.

A volte capita che un utente ritiri il token. Sii pronto per questo.

Archivio dati

Se hai questo design, devi pensare ai dati di cui hai bisogno. Ciò deriva in parte dalla tua interfaccia appena creata. Progettare alcune tabelle per questo e verificare se i dati sono effettivamente recuperabili. Alcuni servizi non ti consentono di acquisire molti dati. Dovresti anche tener conto del fatto che più dati hai bisogno, più diventano pesanti i messaggi sulla privacy. Quindi sii modesto nelle tue esigenze, altrimenti gli utenti non lo useranno.

Per un'ulteriore verifica, è possibile memorizzare i profili in una tabella separata ma collegata ai propri utenti. Questo ti fornirà molte più informazioni su qualcuno.

Controlla anche le leggi locali, per alcuni dati sono necessarie ulteriori precauzioni.

Ultima cosa Non commettere l'errore se non si crea un account sui propri servizi. Se l'utente viene bannato da Facebook, non sarà effettivamente in grado di accedere al tuo servizio. Questa è una situazione che non vuoi creare. Questo è spesso trascurato.


1

Assolutamente preferirei la soluzione che sembra aver già capito: implementare l'autenticazione di terze parti sul tuo sito Web rivolto verso il cliente e quindi associare quei token di autenticazione di terze parti con gli account utente del tuo sito Web e infine attivare la chiamata setSessionID su accesso.

A seconda dell'architettura del tuo sito Web, potresti trovare molto utile utilizzare una libreria come EveryAuth o Passport .


1

I miei due centesimi: non ho mai fatto nulla di simile prima né so come funzionano i meccanismi di accesso FB, Twitter o Google, ma alcuni problemi mi sono venuti in mente non appena ho letto la tua domanda:

  • Accessi multipli: cosa succede se eseguo l'accesso con il mio account Facebook un giorno e il mio account Google il giorno successivo? O contemporaneamente? Trattate questi due account come account univoci e separati o dovreste avere un metodo per associarli e permettermi di accedere ai miei biglietti in entrambi i modi?
  • Affidarsi a identificatori esterni: cosa succede quando Facebook o Twitter decidono di cambiare l'aspetto dei loro identificatori di account? Per illustrare, se BazLogin rappresenta un account univoco utilizzando il codice {4382-af56} ma decide che d'ora in poi gli account avranno 12 cifre perché 8 non erano sufficienti, come si fa a dire {1234-4382-af56} da {selezionato4382 -af56}?

Possiamo affrontare questi due problemi scegliendo di associare gli account esterni a un account interno, non solo a un ID sessione. Quindi, un accesso esterno potrebbe essere solo un gateway per la creazione di un account interno. Se dovessi autenticarmi con più di un metodo di accesso, potresti dirmi che ho già effettuato l'accesso. Se un provider di autorizzazione esterno modifica qualcosa su cui facciamo affidamento, potremmo chiedere all'utente di fornire il nome e la password del proprio account interno e creare un nuova associazione per accessi futuri.

Non sono sicuro di aver affrontato i problemi che avevi in ​​mente, ma in realtà non hai menzionato alcun problema concreto. Spero che la mia risposta sia stata utile, in entrambi i casi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.