2011-01-07 3 views
359

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 utilizzando.Progettazione per l'autenticazione Facebook in un'app iOS che accede anche a un servizio Web protetto

Ipotesi: c'è un'autenticazione nativa (e la registrazione) sistema in vigore per quegli utenti che scelgono di non usare Facebook per il segno in

Dettagli:.

  • Assumiamo voglio offrire l'opzione per un utente di accedere con Facebook senza creare un account/credenziali separati per il nostro sistema.
  • Poiché supportiamo il nostro meccanismo di autenticazione nativo (nome utente e password) abbiamo i nostri ID utente e emettiamo un token di autenticazione che viene utilizzato per le successive interazioni dopo la convalida iniziale delle credenziali.

Sono sorpreso che Facebook non abbia le migliori pratiche per questo nella loro documentazione per sviluppatori. Tutta la documentazione esistente presuppone che si stia realizzando l'autenticazione FB in un sito Web o un'app mobile autonoma senza servizi che richiedono l'autenticazione.

Ecco le mie prime riflessioni su come questo sarebbe stato progettato ma voglio verificare se è corretto.

  1. client apre la Facebook iOS Accesso
  2. segni
  3. UI utente con le credenziali di Facebook e ottiene token di accesso
  4. iOS App passa token di accesso al nostro server
  5. I nostri colloqui di server a FB grafico API che utilizzano l'accesso token a (a) convalidare il token e (b) ottenere l'ID utente FB per quel token di accesso.

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

  6. 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, rilasciamo 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, assegna il nostro ID utente univoco e rilascia il nostro ticket di autenticazione.

  7. Il client passa quindi il ticket di autenticazione alle interazioni successive che richiedono l'autenticazione.

Questo mi sembra il giusto approccio, ma non sono sicuro che manchi qualcosa di follemente di base e che scenda il percorso (complicato) sbagliato.

+0

Come è stato risolto? Sto anche passando il token di accesso e facendo ruotare l'utente sul server. Sembra accademico, ma sto chiedendo. –

+0

Questa è stata la mia implementazione utilizzando rails e ideato: http://stackoverflow.com/questions/7232490/how-to-use-http-authentication-in-devise-with-an-optional-omniauth-token-as- the – Matt

+0

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

risposta

66

Ho appena affrontato questo me stesso, e qui è la parte che mi ha morso:

nel vostro passo 5 ... E 'possibile per un utente di registrarsi per un account con voi completamente separati dai loro Facebook ID, a destra ? Poi qualche altra volta accedono a Facebook ... e tu hai appena creato loro un secondo account e perso il primo.

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

Oltre a ciò, il piano sembra solido.

+6

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

+0

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 si può avere un token di accesso SENZA un ID app inserito in esso. –

11

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 continuerai e usalo.

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

Un possibile exploit di questo sarebbe, per qualcuno di creare il proprio sito o app mobile, ottenere token di accesso per i propri utenti e provare ad autenticarli utilizzando la propria API. Se questo riesce (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 ci sia un modo per convalidare il token di accesso dopo tutto. Vedere la risposta di @Daaniel alla domanda Get application id from user access token (or verify the source application for a token).

+0

L'invio di 'appsecret_proof' dovrebbe impedire questo (si veda [qui] (https://developers.facebook.com/docs/graph-api/securing-requests)) – Tony

+0

@Tony puoi spiegare come' appsecret_proof' aiuta qui? Per quanto ho capito, serve a dimostrare a Facebook che il server conosce la chiave segreta. Tuttavia, ivant si riferiva a un'app dannosa che otteneva token e li inviava alla tua API. Il server può verificare l'ID dell'app, ma l'ID app può essere facilmente falsificato da un'app dannosa. Quindi ... come si potrebbe attenuare questo? – YSK

+1

Puoi verificare che il token sia stato generato per la tua app tramite 'https://graph.facebook.com/app/?access_token= [user_access_token]' che restituisce l'ID app, quindi confrontando gli ID app –

27

utilizzare HTTPS per trasmettere il token di autenticazione al server, come affermato da Facebook

condivisione dei token di accesso alla

Politiche nostri dati proibiscono esplicitamente ogni condivisione di un token di accesso per la tua app con qualsiasi altra app. Tuttavia, consentiamo agli sviluppatori di utilizzare i token di condivisione tra un'implementazione nativa e un'implementazione del server della stessa app (ad esempio utilizzando lo stesso ID app) fino a il trasferimento avviene tramite HTTPS.

3

la soluzione completa funziona.

Forse un'alternativa: perché non solo ottenere l'e-mail sul client dalla richiesta iniziale di servizio sociale e inviare al servizio web? Il servizio web potrebbe semplicemente archiviare l'email e forse anche un social_provider. Comprendo che il tuo servizio web non sarà in grado di convalidare da dove proviene l'email, ma non esiste una relazione di alta 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, fammi sapere quale ovvia cosa mi manca che rende l'approccio basato su e-mail sciocco ...

+3

che ho potuto trovare facilmente fuori come il client sta parlando al server. Quindi potrei semplicemente inviare e-mail fino a ottenere un successo. C'è sempre bisogno di qualche forma di verifica – Chris

+5

Alta fiducia e cliente? Mai nella stessa frase, per favore. Tranne frase precedente ovviamente. – EralpB