Architecture Design - REST API zur Unterstützung von Facebook Login von Mobile App gemacht

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 das folgende Diagramm verwenden, um mein Design zu verstehen.

Es gibt zwei Autorisierungsstufen:

Zuerst ist "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 ein langlebiges access_token an den Client zurück, das für alle nachfolgenden Aufrufe verwendet werden soll. Hier meine Frage:

Q1) Sie sehen, dass der Client client_key und client_secret sendet, und ich speichere sie in client_info table. 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 benutzen?

Q3) Um besonders sicher zu sein, fordere ich Clients auf, 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 Ссылка . Und es ist hash_hmac('sha256', access_token, client_secret)

F4) Wir haben nur unsere eigene mobile App (jeweils für iOS und Android) und bieten keinen Dritten an, unsere API zur Entwicklung anderer Apps zu verwenden. Das bedeutet, dass unsere Tabelle client_info nur zwei Zeilen pro Typ von Apps hat. Ist es in Ordnung, dass wir im App-Code client_key und client_secret fest codieren? Wenn ja, in Zukunft, wenn wir ein neues Geheimnis entwerten und verwenden müssen, wie werden wir dann diese Informationen ersetzen?

F5) Da es seit einigen Jahren unsere eigenen Apps sind, würde es mehrere access_token geben, die gegen die gleichen 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 entschließt sich der Benutzer, einige Aktionen in meiner App durchzuführen. Dazu müssen sich die Benutzer in seinem Konto anmelden. Klicken Sie für diesen Benutzer auf "Facebook Login". Meine App ruft die ID von facebook access_token und fb von Facebook ab und übergibt diese Informationen an den API-Server (wie im 2. Diagramm gezeigt). 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 verbunden sind, zusammen mit dem FB-Zugriffstoken, um unser eigenes user_access_token zu generieren, sagen wir utoken . Und übergeben Sie das utoken zurück an den Client, um es bei allen nachfolgenden benutzerspezifischen API-Aufrufen zurückzugeben. Hier sind meine Fragen:

Q1) Ist es in Ordnung, den utoken in der Datenbank, user_token table zu speichern? Sollte diese utoken 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) Bei jedem benutzerspezifischen API-Aufruf sollte ich Facebook jedes Mal anrufen, um zu überprüfen, ob facebook access_token noch gültig ist? Ich glaube, ich sollte nicht, denn das wird mir nichts bringen. Bitte beachten Sie, dass Facebook NUR für "Facebook Login" verwendet wird.

Q3) Welche Informationen sollte ich verschlüsseln, um utoken zu generieren? Ich denke, ein hash oder assoziatives Array von Benutzer email , user id , role und facebook token 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?

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

F5) Bitte beachten Sie, dass Benutzer möglicherweise mehrere Geräte haben, die mit denselben Anmeldeinformationen angemeldet sind. Das bedeutet, dass wir in der Tabelle user_token mehrere utokens für diese eingeloggte Sitzung speichern müssen, während sie alle zum selben Benutzer gehören. Klingt das richtig?

Ein Designvorschlag, der meinem etwas ähnlich ist REST API für die Website die Facebook zur Authentifizierung nutzt

    
JVK 14.05.2015, 06:11
quelle

1 Antwort

0

Q1.1: 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 OAuths Implicit flow verwenden

Q1.2: Angenommen das Token ist kurzlebig, kein Problem beim Zwischenspeichern. 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 zum Beispiel jemand Zugang zu dem Token erhält, ist sein Zugriff auf das System zeitlich begrenzt.

Q1.3: Schau dir die Facebook Dokumentation an:

  

Graph-API-Aufrufe können von Clients oder von Ihrem Server im Auftrag von Clients ausgeführt werden. Aufrufe von einem Server können besser gesichert werden, indem Sie einen Parameter namens appsecret_proof hinzufügen.

Es besagt, dass appsecret_proof für Aufrufe 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 Tokens kurzlebig sein. Wenn ihre Lebensdauer die gleiche wie die der Anmeldeinformationen ist, die leben, bis der Benutzer sie ändert, dann verlieren Token ihren Zweck.

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

Q2.2: Das glaube ich 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 verwendest es nur zum Einloggen.

Q2.3: Scheint nicht schlecht, aber überprüfe noch einmal die Oauth-Spezifikation, da du scheinbar einen Impliziten Fluss bildest und JWT-Token verwendest. Was Sie in Ihrem Token speichern möchten, scheint in Ordnung.

Q2.4: JWT-Tokens 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!.

    
Daniel Cerecedo 29.06.2017 08:39
quelle