API REST per sito Web che utilizza Facebook per l’autenticazione

Abbiamo un sito web in cui l’ unico modo per accedere e autenticarsi con il sito è con Facebook (questa non era la mia scelta). La prima volta che accedi con Facebook, un account viene creato automaticamente per te.

Ora vogliamo creare un’applicazione per iPhone per il nostro sito e anche un’API pubblica che consenta ad altri di utilizzare il nostro servizio.

Questa domanda riguarda come autenticare con il nostro sito web dall’app / API ed è suddiviso in 2 parti:

  1. Qual è il modo corretto di gestire l’autenticazione REST da un’API a un sito Web che utilizza solo Facebook OAuth come metodo di autenticazione?

    Ho letto e studiato molto sui metodi standard di autenticazione per l’API REST. Non possiamo usare metodi come Basic Auth su HTTPS , poiché non ci sono credenziali per un utente in quanto tale. Qualcosa di simile sembra essere solo per l’autenticazione delle applicazioni che utilizzano l’API.

    Attualmente, il modo migliore che riesco a pensare è di ottenere / endize sulla nostra API, redirect a Facebook OAuth, quindi redirect nuovamente al sito e fornire un “token” che l’utente dell’API può utilizzare per l’autenticazione successiva. richieste.

  2. Per un’applicazione ufficiale che creiamo, non avremmo necessariamente bisogno di utilizzare l’API pubblica allo stesso modo. Quale sarebbe il modo migliore per parlare al nostro sito Web e autenticare gli utenti?

Comprendo (penso) come autenticare le applicazioni di terze parti che utilizzano la nostra API, utilizzando le chiavi API (pubbliche) e le chiavi segrete (private). Tuttavia, quando si tratta di autenticare l’utente che sta usando l’app, mi sento piuttosto confuso su come farlo quando l’unico modo per autenticare un utente è Facebook.

Mi sento come se mi mancasse qualcosa di molto ovvio, o non capisco appieno come funzionano le API pubbliche REST, quindi qualsiasi consiglio e aiuto sarebbe molto apprezzato.

AGGIORNAMENTO: vedi sotto

Ho riflettuto molto anche su questa domanda. Non è ancora del tutto chiaro per me, ma ecco la strada che sto pensando di andare. Sto creando un’API REST che i miei utenti autorizzano solo con Facebook Connect.

Sul CLIENTE:

  1. Usa l’API di Facebook per accedere e ottenere un codice OAUTH2.
  2. Scambia questo codice per un token di accesso.
  3. In ogni chiamata alla mia API personalizzata includerò l’ID utente di Facebook e il token di accesso.

Sull’API (per ogni metodo che richiede l’autenticazione dell’utente):

  1. Fai una richiesta al grafico di Facebook / me usando il token di accesso dall’alto.
  2. Verificare che l’ID utente di Facebook restituito corrisponda all’ID utente passato alla mia API dall’alto.
  3. Se il token di accesso è scaduto, è necessaria una comunicazione aggiuntiva.

Devo ancora provare questo. Come suona?

— Aggiornamento: 27 luglio 2014 per rispondere alla domanda —

Io uso lo scambio sopra solo una volta al momento dell’accesso. Una volta determinato quale utente sta effettuando l’accesso, creo il mio token di accesso e quel token viene utilizzato da quel punto in poi. Quindi il nuovo stream sembra così …

Sul CLIENTE:

  1. Usa l’API di Facebook per accedere e ottenere un codice OAUTH2.
  2. Scambia questo codice per un token di accesso.
  3. Richiedi un token di accesso dalla mia API, incluso il token di Facebook come parametro

Sull’API

  1. Ricevi richiesta di token di accesso.
  2. Fai una richiesta al grafico di Facebook / me usando il token di accesso di Facebook
  3. Verifica che l’utente di Facebook esista e corrisponda a un utente nel mio database
  4. Crea il mio token di accesso, salvalo e restituiscilo al client da utilizzare da questo punto in avanti

Questa è la mia implementazione utilizzando JWT (Token Web JSON), sostanzialmente simile alla risposta aggiornata di Chris. Ho usato Facebook JS SDK e JWT.

Ecco la mia implementazione.

  1. Cliente: usa Facebook JS SDK per accedere e ottenere il token di accesso.

  2. Client: richiede JWT dalla mia API chiamando /verify-access-token end /verify-access-token endpoint.

  3. MyAPI: riceve il token di accesso, verificarlo chiamando /me endpoint dell’API di Facebook.

  4. MyAPI: se il token di accesso è valido, trova l’utente dal database, accede all’utente se esiste. Crea una JWT con i campi obbligatori come payload, imposta una scadenza, firma con la chiave segreta e rimanda al client.

  5. Client: memorizza il JWT nella memoria locale.

  6. Client: invia il token insieme alla richiesta per la successiva chiamata API.

  7. MyAPI: convalidare il token con la chiave segreta, se il token è valido, scambiare il token con uno nuovo, inviarlo di nuovo al client insieme alla risposta dell’API. (Nessuna chiamata API esterna per la verifica del token qui dopo) [se il token è client di richiesta non valido / scaduto per autenticarsi di nuovo e ripetere da 1]

  8. Client Sostituisce il token memorizzato con quello nuovo e lo utilizza per la successiva chiamata API. Una volta raggiunta la scadenza del token, il token termina con la revoca dell’accesso all’API.

Ogni token viene usato una volta.

Leggi ulteriori risposte su sicurezza e JWT

Quanto è sicuro JWT

Se riesci a decodificare JWT, come sono sicuri?

JSON Web Tokens (JWT) come token di identificazione e autenticazione dell’utente

Sto cercando di rispondere alla stessa domanda e ho letto molte letture di recente …

Non avrò la “risposta”, ma le cose stanno diventando un po ‘più chiare per me. Hai letto i commenti nell’articolo che hai menzionato ? Li ho trovati davvero interessanti e utili.

Di conseguenza, e alla luce di come si sono evolute le cose da quando è stato scritto il primo articolo, ecco cosa penso che farò:

  • HTTPS ovunque – questo ti permette di dimenticare HMAC, firma, nonce, …

  • Usa OAuth2:

    • Quando le richieste di autenticazione provengono dalle mie app / sito Web, utilizzare questo “trucco” (o una variante di esso) descritto in una risposta all’articolo menzionato prima.

    • Nel mio caso, ho due tipi di utenti: quelli con credenziali di accesso / password classiche e quelli che si sono registrati con Facebook Connect.
      Quindi fornirei un modulo di accesso regolare con il pulsante “Accedi con Facebook”. Se l’utente effettua il login con le sue credenziali “classiche”, li invierei al mio endpoint OAuth2 con un grant_type=password .
      Se sceglie di accedere tramite Facebook, penso che sarebbe un processo in due fasi:

      • Per prima cosa, usa Facebook iOS SDK per aprire una FBSession
      • Quando ciò è fatto e l’app viene restituita, dovrebbe esserci un modo per ottenere un ID di Facebook per quell’utente. Manderei questo ID da solo al mio endpoint OAuth2 con una concessione di estensione compresa dal mio server come “utilizzando un ID utente FB”.

Tieni presente che sto ancora facendo ricerche approfondite su tutte queste cose, quindi potrebbe non essere una risposta perfetta … forse nemmeno una corretta! Ma penso che sarebbe un buon punto di partenza. L’idea di utilizzare una “concessione di estensione” per l’autenticazione di Facebook potrebbe comportare la necessità di registrarla per fare le cose correttamente? Non sono molto sicuro.

Comunque, spero di essere stato in grado di aiutarti anche un po ‘, e che almeno possa iniziare una discussione per trovare la migliore soluzione a questo problema 🙂

Aggiornare
L’accesso a Facebook non è una soluzione come indicato nei commenti: chiunque potrebbe inviare un ID utente arbitrario e accedere come utente sull’API.

Che ne dici di farlo in questo modo:

  • Mostra un modulo di accesso con un pulsante “Login Facebook”
  • Se viene scelto questo metodo di accesso, agire come l’SDK di Facebook: aprire una pagina Web dal proprio server di autenticazione, che avvierà il login di Facebook.
  • Una volta che l’utente ha effettuato l’accesso, Facebook utilizzerà l’URL di reindirizzamento per confermare; fare in modo che l’URL punti a un altro endpoint del server di autenticazione (possibilmente con un parametro aggiuntivo che indica che la chiamata proviene da un’app?)
  • Quando viene colpito l’endpoint di autenticazione, l’autenticazione può identificare in modo sicuro l’utente, conservare l’ID utente FB / sessione FB e restituire un token di accesso alla tua app utilizzando uno schema URL personalizzato, proprio come farebbe l’SDK di Facebook

Sembra migliore?