Progettare per l'autenticazione di Facebook in un'app iOS che accede anche a un servizio Web sicuro


402

Obiettivo: consentire a un utente di eseguire l'autenticazione con Facebook in un'applicazione iOS che richiede l'accesso a un servizio Web protetto che sto eseguendo.

Presupposti: esiste un sistema di autenticazione (e registrazione) nativo per quegli utenti che scelgono di non utilizzare Facebook per accedere.

Dettagli:

  • Supponiamo di voler offrire la possibilità a un utente di accedere con Facebook senza creare un account / credenziali separato per il nostro sistema.
  • Poiché supportiamo il nostro meccanismo di autenticazione nativo (nome utente e password) abbiamo i nostri ID utente ed emettiamo un token di autenticazione che viene utilizzato per le interazioni successive dopo la convalida iniziale delle credenziali.

Sono sorpreso che Facebook non abbia le migliori pratiche per questo nella documentazione per gli sviluppatori. Tutta la documentazione esistente presuppone che tu stia inserendo l'autenticazione FB in un sito Web o un'app mobile autonoma senza servizio che richiede autenticazione.

Ecco i miei pensieri iniziali su come questo sarebbe stato progettato, ma voglio convalidare se è corretto.

  1. Il client apre l'accesso iOS di Facebook
  2. L'interfaccia utente accede con le credenziali di Facebook e ottiene il token di accesso
  3. L'app iOS passa il token di accesso al nostro server
  4. Il nostro server comunica con l'API del grafico FB utilizzando il token di accesso per (a) convalidare il token e (b) ottenere l'ID utente FB per quel token di accesso.

    es. Il nostro server chiamerebbe https://graph.facebook.com/me/?access_token=XYZ che restituirebbe le informazioni del profilo in un oggetto JSON

  5. Supponendo che sia valido, il nostro server estrae l'ID utente dall'oggetto JSON e controlla se l'utente ha già un account. In tal caso, emettiamo il nostro ticket di autenticazione al client da utilizzare per quella sessione. Se l'utente non ha un account, ne creiamo uno nuovo con l'ID utente di Facebook, assegniamo il nostro ID utente univoco ed emettiamo il nostro ticket di autenticazione.

  6. Il client quindi restituisce il ticket di autenticazione sulle interazioni successive che richiedono l'autenticazione.

Questo mi sembra l'approccio giusto ma non sono sicuro che mi manchi qualcosa di follemente di base e stia andando sulla strada sbagliata (complicata).


1
Come è stato risolto? Sto anche cercando di passare il token di accesso e di far girare l'utente sul server. Sembra accademico, ma lo sto chiedendo.
Chris Van Buskirk,

Questa è stata la mia implementazione usando rotaie e idea: stackoverflow.com/questions/7232490/…
Matt,

Perché non passare l'intero auth_hash invece di dover effettuare due chiamate all'API FB (una dal dispositivo iOS e una volta dal server)?
bsiddiqui,

1
Cosa succede se si desidera accedere da un dispositivo diverso (ovvero non si dispone del proprio ticket di autenticazione)? E se ricevi solo un nuovo ticket di autenticazione, cosa impedisce a qualcuno di dirottare l'id / token di Facebook lungo la strada e usarlo sul suo dispositivo?
Amitloaf,

Per curiosità, nel passaggio 5, perché emettere il proprio ticket di autorizzazione? Non potresti utilizzare il token di accesso di Facebook per ogni successiva chiamata al server? Mi rendo conto che richiederebbe una chiamata dal server all'API di Facebook per ogni app -> chiamata dal server anziché solo la prima.
Anders,

Risposte:


80

Mi sono appena occupato di questo, ed ecco la parte che mi ha morso:

Nel tuo passaggio 5 ... È possibile che un utente registri un account con te completamente separato dal proprio ID Facebook, giusto? Poi un'altra volta hanno effettuato l'accesso con Facebook .... E tu li hai appena creati un secondo account e hai perso il loro primo.

È necessario un modo per accedere al servizio Web, quindi accedere a Facebook e acquisire l'associazione tra l'ID Facebook e l'account locale.

A parte questo, il tuo piano sembra solido.

Aggiornamento : Facebook ha aggiunto un documento che delinea un tale scenario QUI


7
Sì, l'ho considerato e tu sei perfetto. Abbiamo in programma di unire gli account se si tratta dello stesso indirizzo e-mail e, in caso contrario, creeremo un altro modo per unirli.
TMC

Quale libreria server stai utilizzando sul lato server per effettuare la richiesta?
TimLeung,

7
@TimLeung - La mia comprensione è che un token di accesso incorpora l'ID app e che non è possibile avere un token di accesso SENZA un ID app inserito al suo interno.
Dan Ray

1
@TimLeunge: stiamo usando l'API Graph per le richieste con il token di accesso dell'utente.
TMC,

29

Utilizzare https per trasmettere il token di autenticazione al server, come indicato da Facebook

Condivisione di token di accesso

Le nostre politiche sui dati vietano esplicitamente qualsiasi condivisione di un token di accesso per la tua app con qualsiasi altra app. Tuttavia, consentiamo agli sviluppatori di condividere token tra un'implementazione nativa e un'implementazione server della stessa App (ovvero utilizzando lo stesso ID app) purché il trasferimento avvenga tramite HTTPS.


16

Un problema che posso vedere con questa strategia è che qualcuno può darti un token di accesso ottenuto per un'altra app di Facebook. Per quanto ne so, non c'è modo di verificare che il token di accesso sia per la tua applicazione, quindi proseguirai e lo utilizzerai.

Non sembra molto dannoso, però. Generalmente le persone / app cercano di proteggere i token di accesso, piuttosto che condividerli.

Un possibile exploit di questo sarebbe, per qualcuno creare il proprio sito o app mobile, ottenere token di accesso per i propri utenti e provare ad autenticarli, usando la tua API. Se ciò ha esito positivo (l'utente ha un account Facebook nel tuo sito), il sito dannoso sarà in grado di utilizzare la tua API impersonando l'utente.

È un po 'lungo, ma penso che potrebbe funzionare.

Modifica: sembra che dopo tutto ci sia un modo per convalidare il token di accesso. Vedi la risposta di @Daaniel alla domanda Ottieni l'ID applicazione dal token di accesso dell'utente (o verifica l'applicazione di origine per un token) .


L'invio appsecret_proofdovrebbe impedirlo (vedi qui )
Tony

@Tony puoi spiegare come appsecret_proofaiuta qui? Per quanto ho capito, serve per dimostrare a Facebook che il server conosce la chiave segreta. Tuttavia, ivant si riferiva a un'app dannosa che otteneva token e quindi li inviava all'API. Il server può verificare l'ID app, ma l'ID app può essere facilmente falsificato da un'app dannosa. Quindi ... come mitigarlo?
YSK,

3
Puoi verificare che il token sia stato generato per la tua app attraverso la https://graph.facebook.com/app/?access_token=[user_access_token]quale restituisce l'ID app e quindi confrontando gli ID app
Nader Alexan

4

la tua soluzione funziona totalmente.

Forse un'alternativa: perché non ottenere semplicemente l'e-mail sul client dalla richiesta iniziale di servizio sociale e inviarla al tuo servizio web? Il servizio web potrebbe semplicemente archiviare l'e-mail e forse anche un social_provider. Comprendo che il tuo servizio web non sarà in grado di convalidare la provenienza dell'email, ma non esiste una relazione di fiducia tra il tuo servizio web e il tuo cliente? Se c'è, sembra che tu possa dipendere dall'e-mail proveniente dal posto giusto. Qualcuno per favore fatemi sapere quale cosa ovvia mi manca che rende sciocco l'approccio basato su e-mail ...


3
Potrei facilmente scoprire come il client sta parlando con il server. Quindi potrei semplicemente lanciare e-mail fino a quando non avrò un colpo. Ci deve sempre essere una qualche forma di verifica
Chris,

5
Alta fiducia e cliente? Mai nella stessa frase, per favore. Tranne la frase precedente ovviamente.
EralpB
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.