2015-05-14 5 views
9

Ich versuche REST APIs zu entwerfen, um verschiedene mobile Clients (iOS und Android Apps) zu unterstützen. Diese Apps ermöglichen die Anmeldung von Nutzern mit Facebook-Login und unserer eigenen E-Mail-Authentifizierung. Sie können unten die Abbildung auf mein DesignArchitecture Design - REST API zur Unterstützung von Facebook Login von Mobile App

Design flow

Es gibt zwei Berechtigungsstufen stattfinden, zu verstehen:

Erstens ist ein „Client (oder App) Authorization“, die OAuth2 verwendet. Also, wenn Benutzer unsere App auf dem mobilen Gerät installieren, und startet App, dann allererste Sache, App macht "Client (App) Authorization" wie im obigen Diagramm (1. Bild) gezeigt. Und der Server sendet einen langlebigen access_token an den Client zurück, um ihn für alle nachfolgenden Anrufe zu verwenden. Hier sind meine Frage:

Q1) Sie können sehen, Client sendet client_key und client_secret und ich speichern sie in client_info Tabelle. Sollte dieses Geheimnis im Klartext oder im entschlüsselbaren Format sein? Wenn ich es verschlüssle, muss ich den Verschlüsselungsschlüssel irgendwo in meinem System aufbewahren. Wie wird es also sicher machen? Auch bei jedem Anruf wird die Entschlüsselung ein Overhead sein.

Q2) Ist es in Ordnung, access_token für den Client im Nur-Text-Format in Redis zu cachen und diesen Cache zuerst zu verwenden?

Q3) Um extra sicher zu sein, bitte ich die Kunden, appsecret_proof zu senden, um sicherzustellen, dass das access_token, das sie senden, nur zu diesem Client gehört. Es verwendet das gleiche Konzept wie Facebook https://developers.facebook.com/docs/graph-api/securing-requests#appsecret_proof. Und es ist hash_hmac('sha256', access_token, client_secret)

Q4) Wir haben nur unsere eigene 2 mobile App (jeweils für iOS und Android) und nicht die Bereitstellung von Dritten, um unsere API zu verwenden, um andere Anwendungen zu entwickeln. Das bedeutet, dass unsere Tabelle client_info nur zwei Zeilen pro Typ von Apps hat. Also ist es in Ordnung, dass wir in App-Code client_key und client_secret fest codiert halten? Wenn ja, in Zukunft, wenn wir ein neues Geheimnis entwerten und verwenden müssen, wie werden wir dann diese Informationen ersetzen?

Q5) Da es seit einigen Jahren unsere eigenen Apps ist, würde es mehrere access_token geben, die gegen client_key und client_secret erstellt werden. Um alle zu speichern, ist es eine gute Idee, client_key als Schlüssel und array of all access_tokens als Wert in redis zu speichern. In Zukunft, wenn wir unsere API für Dritte öffnen, kann dieses Design für Redis-Speicher noch skalieren?

=================

Später, Benutzer entscheidet, einige Aktionen auf meine app ausführen, für die wir Benutzer müssen auf sein Konto einzuloggen. Klicken Sie für diesen Benutzer auf "Facebook Login". Meine App bekommt facebook access_token und fb Benutzer-ID von Facebook und übergibt diese Informationen an API-Server (wie im 2. Diagramm dargestellt). Der API-Server nimmt dieses Token und ruft die Facebook-API auf, um seine access_token zu validieren. Sobald das Token validiert ist, verwendet der Server einige Metadaten, die mit diesem Benutzer zusammenhängen, zusammen mit dem FB-Zugriffstoken, um unser eigenes user_access_token zu generieren, sagen wir utoken. Und übergeben Sie diese utoken zurück an den Client, um sie bei allen nachfolgenden benutzerspezifischen API-Aufrufen zurückzugeben. Hier meine Fragen sind:

Q1) Ist es in Ordnung, das utoken in Datenbank, user_token Tabelle zu speichern. Sollte diese utoken im Klartext sein oder sollte es im entschlüsselbaren Format sein? Wenn ich es verschlüssle, muss ich den Verschlüsselungsschlüssel irgendwo in meinem System aufbewahren. Wie wird es also sicher machen? Auch bei jedem Anruf wird die Entschlüsselung ein Overhead sein.

Q2) In jedem Benutzer bestimmte API Anrufe, sollte ich Facebook jedes Mal anrufen, um zu überprüfen facebook access_token ist noch gültig? Ich glaube, ich sollte nicht, denn das wird mir nichts bringen. Bitte beachten Sie, Facebook wird NUR für "Facebook Login" verwendet.

Q3) Welche Informationen sollte ich verschlüsseln, um utoken zu generieren? Ich denke, ein Hash oder assoziative Array von email, user id, und facebook token des Benutzers zu haben und dann diese Datenstruktur zu serialisieren und schließlich zu verschlüsseln. Glaubst du, das wäre gut genug? Ich verstehe es nach meiner Anforderung, aber als Standard oder gemeinsame App, sind sie gut genug? Oder gibt es Best Practices?

Q4) Sollte der Client utoken in seinem Cookie/Cache speichern? Ist das nicht gruselig?

Q5) Bitte beachten Sie, dass der Benutzer mehrere Geräte haben kann, die mit denselben Benutzerdaten angemeldet sind. Das heißt, in der user_token-Tabelle müssten wir mehrere utokens für diese eingeloggte Sitzung speichern, während sie alle demselben Benutzer gehören. Klingt das richtig?

Ein Entwurf Vorschlag etwas smiliar REST API for website which uses Facebook for authentication

Antwort

0

Q1.1 verminen: Nein !. Client-Anmeldeinformationen sollen nicht auf diese Weise verwendet werden. Wenn es sich bei Ihrem Client um eine Single Page App oder eine Mobile App handelt, müssen Sie Ihre Client-Anmeldeinformationen in einer unsicheren Umgebung, dem Computer des Benutzers, speichern. Sie sollten den impliziten OAuth-Fluss verwenden

Q1.2: Angenommen, das Token ist kurzlebig, kein Problem bei der Zwischenspeicherung. Der Schlüssel zu OAuth besteht nicht nur darin sicherzustellen, dass Sie sich auf andere Anwendungen verlassen können, um Ihre Benutzer zu authentifizieren, sondern auch darin, dass Sie Benutzer- oder Anwendungs-Anmeldeinformationen, die langlebig sind, effektiv durch ein kurzlebiges Token ersetzen. Wenn also jemand Zugriff auf das Token erhält, ist sein Zugriff auf das System zeitlich begrenzt.

F1.3: Schauen Sie sich, dass Facebook-Dokumentation:

Graph-API-Aufrufe können von Kunden oder von Ihrem Server im Namen von Kunden vorgenommen werden. Anrufe von einem Server können besser durch Hinzufügen eines Parameters namens appsecret_proof gesichert werden.

Es besagt, dass appsecret_proof für Anrufe vom Server im Auftrag des Benutzers verwendet werden soll. Der Punkt hier hat mit Q1.1 zu tun. Wenn Sie Ihren client_secret auf dem Gerät Ihres Benutzers speichern, könnten sie appsecret_proof generieren.

Q1.4: Wieder nein! Sie sollten die OAuth-Spezifikation gut lesen und die verschiedenen Ablaufarten und den Zeitpunkt der Verwendung verstehen. Bedenken Sie auch, dass die API öffentlich ist, wenn Sie eine API für Ihre App bereitstellen. Der einzige Unterschied ist, dass es nicht dokumentiert ist. Das Gleiche wird mit einer Web App passieren. Sobald es im Internet ist, könnte ich einen Schaber schreiben und die Web App missbrauchen. Das ist völlig normal, bedenken Sie, dass alles im Internet nicht privat ist, es ist einfach undokumentiert.

Q1.5: Auch hier sollten Token kurzlebig sein. Wenn ihre Lebensdauer die gleiche ist wie die der Anmeldeinformationen, die so lange bestehen, bis der Benutzer sie ändert, verlieren die Tokens ihren Zweck.

Q2.1: Sie sollten dieses Token speichern Eine ReST-Architektur verwendet eine Client-Cache-Einschränkung.

Q2.2: Ich glaube nicht. Facebook teilt Ihnen gerade mit, dass der Benutzer, der dieses Token erhalten hat, eine Identität hat (z. B. eine E-Mail), die Sie einem Benutzer in Ihrem System zuordnen können. Sobald Sie diesen Verband kennen, sollten Sie sich nicht viel um den Facebook-Token kümmern, sondern um Aufrufe an Facebook-API. Aber ass du sagst, du benutzt es nur zum Login.

Q2.3: Scheint nicht schlecht, aber überprüfen Sie erneut die Oauth-Spezifikation, da Sie anscheinend einen impliziten Fluss erstellen und JWT-Tokens verwenden. Was Sie in Ihrem Token speichern möchten, scheint in Ordnung zu sein.

Q2.4: JWT-Token müssen vom Client zwischengespeichert werden. Nichts Unheimliches, weil sie für den Client undurchsichtig sind, da sie verschlüsselt sind. Der Client sendet das JWT-Token mit jeder Anforderung und der API-Server entschlüsselt das Token mit einem privaten Schlüssel (der nie außerhalb des Servers verfügbar war) und kann die Identität des Benutzers überprüfen.

Q2.5: Denken Sie an kurzlebige Token. Token müssen ablaufen !.