AWS Cognito-Benutzerpools in der iOS (Swift) -App

8

Ich versuche, die neuen AWS Cognito User Pools in meiner iOS (Swift) -App zu implementieren, aber ich habe Probleme, den Anmeldevorgang zu starten. Ich versuche im Wesentlichen, dem Beispiel zu folgen, das verfügbar ist hier .

Das habe ich bisher:

AppDelegate:

%Vor%

LogInViewController:

%Vor%

Es scheint nichts zu passieren, wenn ich den Login-Knopf drücke, obwohl ich, wenn ich es wieder anklicke, eine NSInternalInconsistencyException bekomme (was ich glaube, weil das AWSTask-Ergebnis bereits gesetzt wurde).

Jede Hilfe mit diesem würde geschätzt werden. Ich verwende das AWS SDK für iOS Version 2.4.1.

UPDATE:

Keine Lösung für mein ursprüngliches Problem, aber ich war in der Lage, Benutzerpools mit der expliziten Anmeldemethode anstatt mit der Delegate-Methode arbeiten zu lassen (siehe Seite für Details). Hier ist der Code von meinem SignInViewController:

%Vor%

Um einen AWS-Service zu nutzen (der sich in meinem Fall in einer anderen Region als Cognito befindet), habe ich einen neuen Credentials-Provider mit dem Benutzerpool erstellt:

%Vor%

Ein zusätzliches Problem ist, dass ich diesen Fehler jedes Mal sah, wenn ich die App startete: "Ich konnte die Werte 'AWSDefaultRegionType', 'AWSCognitoRegionType' und 'AWSCognitoIdentityPoolId' in der Datei 'info.plist' nicht finden." Dies scheint mit Fabric zu tun zu haben, die ich verwende, um Abstürze zu verfolgen. Ich habe das gelöst, indem ich diese Zeile im AppDelegate ändere:

%Vor%

dazu:

%Vor%

Ich hoffe, das hilft jemand anderem.

    
Elliot 12.05.2016, 02:38
quelle

10 Antworten

11

Update 6: (und diesmal wirklich endgültig)

Es ist erwähnenswert, dass (endlich) AWS den AWS Mobile Hub dazu gebracht hat, eine sehr schöne Demo-App zu erstellen, die User Pools als SignInProvider enthält (auch mit Google und Facebook). Die Architektur ist (meiner Meinung nach) exzellent (sie haben Identity Management getrennt und Anmeldeinformationen von der Authentifizierung erhalten) Schau es dir an

Update 5: (und endgültig)

Es gibt eine ziemlich vollständige Beispielimplementierung und eine Dokumentation, wie es in dieser anderen Antwort funktioniert.

iOS - AWS MobileHub Anmeldung mit Entwickler authentifizierter Anbieter

Update 4:

Wenn Sie Zugriff auf AWS-Services erhalten möchten, sind weitere Schritte erforderlich.

Es stellt sich heraus, dass Sie dadurch nicht mit Cognito Federated Identities authentifiziert werden (die Anzahl der Logins im Identity Browser bleibt auf 0). Um dies zu beheben, müssen Sie einen credentialsProvider einrichten und "credentialsProvider.getIdentityId" ausführen. Danach werden die Logins positiv und Sie können Services von AWS basierend auf Ihrer authentifizierten Rolle erhalten.

Wenn Sie versuchen, sowohl den authentifizierten als auch den nicht authentifizierten Zugriff für Ihre mobile App auszuführen, müssen Sie einen AWSAnonymousCredentialsProvider (in einer separaten Dienstkonfiguration) erstellen. Dann Sie selbst.credentialsProvider? .invalidateCachedTemporaryCredentials () und self.credentialsProvider? .clearCredentials () beim Abmelden und die getidentityid erneut mit der anonymen Service-Konfiguration tun, und Sie erhalten eine anonyme ID. (Hinweis: Ich fand, dass es so aussieht, als ob Sie cleekeychain auf dem credentialsProvider mit einer neuen ID jedes Mal starten, wenn sich ein Benutzer abmeldet, was Ihre kostenlosen 50.000 IDs ziemlich schnell verbrennen könnte.)

Update 3:

Eine github-Beispiel-App für AWS-Benutzerpools für IOS wurde in Swift hochgeladen.

Ссылка

Update 2:

Ich habe AWS User Pools endlich richtig in Swift arbeiten lassen

Mein Problem war, dass jedes Mal, wenn der Authentifizierungsstart stattfand, ein Authentifizierungsfehler in einem anderen Viewcontroller (mein Fehler) aufgetreten ist. Ich endete mit einer Reihe von ihnen läuft auf die Fertigstellung Rückkehr warten, die nie kam und die API war "still" (zeigte keine Fehler). Die API merkt nicht, dass sie mehrmals initiiert wird (jedes Mal von einem anderen viewController), so dass sie sich im Hintergrund immer wieder anmelden kann. Es gibt nicht genug Code in der ursprünglichen Post, um zu sehen, ob Sie das gleiche Problem haben.

Sie müssen vorsichtig sein, der AWS-Beispielcode (in Objective-C) hat zwei Navigationscontroller und der Code verwendet sie erneut. Ich mag es nicht, wie die Beispiel-App den angemeldeten View-Controller aufblinkt, bevor der Authentifizierungsdelegat losgeht, und ich habe versucht, das in der schnellen Version zu verbessern, und das hat mein Problem verursacht.

Die AWS User Pools-API ist so eingerichtet, dass sie mit einer Storyboard- oder App-Struktur arbeitet, die folgendermaßen funktioniert:

1) Ihre App ÜBERNIMMT, dass sie angemeldet ist und löst dann den Delegierten, der die Authentifizierung auslöst, und die Anmeldebildschirme aus, falls dies nicht der Fall ist.

2) Im ursprünglichen angemeldeten Ansichts-Controller ist pool.currentUser () NICHT genug, um die Authentifizierung in Gang zu setzen, die API löst nur dann den Delegierten aus, wenn Sie mehr tun (in meinem Fall user.getDetails ()).

3) Die Authentifizierung wird durch didCompletePasswordAuthenticationStepWithError abgeschlossen. Diese Delegate-Methode wird aufgerufen, wenn Sie einen (oder anderen) Authentifizierungsfehler erhalten und wenn Sie sich erfolgreich authentifizieren. Im Falle einer erfolgreichen Authentifizierung ist der NSError gleich Null und sollte daher als NSError deklariert werden. im Delegierten (dies verursacht eine Warnung). Die API ist Beta, sie werden das wahrscheinlich beheben.

4) Ein weiteres kleines "Gotcha", es kann für Sie offensichtlich sein, hat es mich erwischt, wenn Sie Ihren Benutzerpool in der Konsole definieren Sie zugelassene Apps, und jede dieser Anwendungen HAT VERSCHIEDENE STRINGS für Client-ID-Strings. (Ich habe gerade das gleiche in das Beispiel gesteckt), was schlecht funktioniert (aber keine Fehler meldet). Die API benötigt etwas Arbeit in der Berichtsabteilung. Es ist sehr ausführlich, wenn es funktioniert, aber sagt nichts, wenn Sie es falsch übergeben Client Strings. Es scheint auch nichts zu sagen, wenn Sie (wie ich) die API von verschiedenen Viewcontrollern aus aufrufen. Es nahm nur jede neue Authentifizierungsanfrage von einem anderen Viewcontroller und sagte nichts.

Wie auch immer, es funktioniert jetzt. Ich hoffe, dies hilft Ihr Problem zu lösen.

Aktualisierung:

Ich habe getPasswordAuthenticationDetails endlich ausgeführt.

Es stellt sich heraus, dass es erst für user user.getDetails für den aktuellen Benutzer ausgeführt wird (auch wenn kein aktueller Benutzer vorhanden ist).

Also

let user = appDelegate.pool!.currentUser() let details = user!.getDetails()

führt dazu, dass der Rückruf getPasswordAuthenticationDetails in der zweiten Zeile ausgeführt wird.

Es scheint, dass das AWS UserPool-Konzept ist, dass wir eine App schreiben, die davon ausgeht, dass wir einen angemeldeten Benutzer haben. Wir erhalten Details von diesem Benutzer (zum Beispiel in der ursprünglichen Ansicht Controller) und der Delegat wird ausgelöst, wenn wir keinen Benutzer haben.

In der AWS-Dokumentation für User Pools auf IOS fehlen einige wichtige Konzeptseiten. Diese Seiten sind in der (ansonsten parallelen) Android-Dokumentation enthalten. Ich gebe zu, dass ich (noch Tage) immer noch damit zu kämpfen habe, User Pools schnell zum Laufen zu bringen, aber das Lesen der "Main Classes" und "Key Concepts" Teile der Android-Dokumentation hat mir viel klargemacht. Ich kann nicht sehen, warum es aus dem IOS-Dokument weggelassen wurde.

    
Bruce0 13.07.2016, 00:23
quelle
4

Ich füge nur meine 2 Cent für Leute hinzu, die mit Objective-c und der von Amazon bereitgestellten Beispielanwendung CognitoYourUserPoolsSample arbeiten. @ Bruce0 hat schon alles mit seiner schnellen Lösung abgedeckt. Aber wenn Sie auf dieses Problem stoßen, bei dem getPasswordAuthenticationDetails nicht aufgerufen wird, wenn Sie auf die Anmeldung klicken, liegt das daran, dass Sie nicht [self.user getDetails] aufrufen alle. In der Tat - getDetails löst getPasswordAuthenticationDetails aus. Wenn Sie in der AWS-Beispielanwendung genauer hinsehen, nennen sie das Recht, wenn sie die Anwendung in viewDidLoad des UserDetailTableViewController starten. Dies ist der erste Controller, der geladen wird. Wenn der Benutzer nicht angemeldet ist, löst die getDetails-Antwort den SignInViewController aus. Dies werde ich im Folgenden erläutern. Es ist wie bei einem "myHomeViewController", wo Sie benutzerbezogene Informationen anzeigen möchten. Andernfalls möchten Sie standardmäßig den Anmelde- / Anmeldebildschirm anzeigen.

  • Als allgemeine Faustregel sollten Sie den Cognito-Benutzerpool in Ihrem AppDelegate ( didFinishLaunchingWithOptions ) genau wie in der Beispiel-App verbinden und starten. Stellen Sie sicher, dass Sie das AWSCognitoIdentityInteractiveAuthenticationDelegate hinzufügen und startPasswordAuthentication implementieren, wo Sie den ViewController für die Anmeldung aufrufen. Lassen Sie das AppDelegate sich um das WHAT_TO_DO_IF_USER_NOT_SIGNED_IN kümmern (z. B. den SignInViewController oben) und konzentrieren Sie sich dann auf das WHEN_DOES_THE_USER_NEEDS_TO_SIGNIN irgendwo in Ihrer App.

  • Wenn Sie benutzerspezifische Daten benötigen, teilen Sie der App mit, dass es an der Zeit ist, zu überprüfen, ob der Benutzer angemeldet ist (self.user getDetails). Wenn der Benutzer nicht angemeldet ist, weiß das AppDelegate, was zu tun ist. Es überschreibt die App und zeigt die Anmeldung über allem an. Es könnte also gleich zu Beginn (z. B. Facebook, Twitter usw.) oder anderswo (z. B. Ebay usw.) sein. Rufen Sie einfach am Ende von viewDidLoad [self.user getDetails] auf. Dadurch wird verhindert, dass der aktuelle ViewController vor dem Authentifizierungsschritt angezeigt wird (Anmeldung / Anmeldung). ODER einfach den aktuellen ViewController laden, wenn der Benutzer bereits angemeldet ist.

Wenn Sie die AWS-Benutzerpoolfunktion in Ihrer App verwenden, führen Sie die folgenden Schritte aus:

  1. Finden Sie heraus, wo Sie benutzerspezifische Daten in einem Ihrer YourViewControllers benötigen
  2. rufen Sie in der verwandten ViewDidLoad [self.user getDetails]
  3. auf
  4. Wenn der Benutzer bereits angemeldet ist, dann zeigen Sie mit dem completionHandler von self.user getDetails benutzerspezifische Daten an.
  5. Wenn nicht, wird startPasswordAuthentication automatisch in AppDelegate aufgerufen, wodurch die ViewController-Anmeldung aufgerufen wird, bevor YourViewController angezeigt wird, da Sie benutzerspezifische Daten benötigen
  6. Benutzeranmeldung oder Anmeldung
  7. dissmiss Anmeldung / Anmeldung ViewController und Sie sind wieder in YourViewController, die jetzt mit einigen benutzerspezifischen Daten geladen werden kann.

Die AWS-Beispiel-App ist nicht einfach, aber sie ist wirklich einfach.

    
Foo 28.08.2016 04:47
quelle
2

Danke Elliot. Ich versuche jetzt, die schnelle Version dieses Codes für einige Tage zu schreiben.

Ich habe versucht, das explizite signIn zu verwenden, indem ich den folgenden Code verwende.

%Vor%

Wenn ich korrekte Zugangsdaten zur Verfügung stelle, geht es zum Fehlerblock. Jedes Mal, wenn ich den Code ausführe, wird ein Bestätigungscode an mein Handy gesendet, obwohl ich meinen Benutzer bereits während des Anmeldevorgangs verifiziert habe. Antworttext ist

%Vor%

Wenn ich ein falsches Passwort angegeben habe, lautet der Antworttext

%Vor%

Könnten Sie mir vorschlagen, was ich hier falsch mache?

    
Abhishek Kumar 17.05.2016 15:32
quelle
2

Ich habe auch die gleichen Schritte wie in der ursprünglichen Posterfrage ausgeführt, aber die App wechselt beim Start nie zum Anmeldebildschirm. Ich habe überprüft, dass der Code zum Wechseln zwischen Ansichten korrekt ist, indem Sie ihn direkt in die AppDelegate.application (....) -Methode platzieren. Es scheint, dass die Methode startPasswordAuthentication (...) delete nie aufgerufen wird. Kann jemand einen Link zu einer Beispielanwendung veröffentlichen, die mithilfe des AWSCognitoIdentityInteractiveAuthenticationDelegate-Protokolls zum Anmeldebildschirm wechselt?

    
ranji 10.07.2016 19:28
quelle
1

Es scheint, dass die Methode "startMultiFactorAuthentication" nicht im Delegaten implementiert ist, deshalb wird ein falsches Passwort erkannt, aber wenn das korrigierte Passwort angegeben wird, wird es an MFA eskaliert, aber die Start-MFA-Funktion wurde nicht im Delegaten und gefunden daher schlägt die Anmeldung fehl.

    
Hardik Shah 19.05.2016 19:15
quelle
0

Für mich habe ich diesen Fehler immer erhalten, weil ich eine Bestätigung habe, aber ich habe den Benutzer NICHT verifiziert, bevor ich mich anmelde. Sobald es verifiziert wurde, hat alles funktioniert.

    
helloGo 09.06.2016 07:12
quelle
0

Ich befolge das gleiche Beispiel und behandle das gleiche Problem, und ich habe es nicht vollständig gelöst, aber ich vermute stark, dass das Problem etwas damit zu tun hat, dass diese Funktion niemals ausgeführt wird:

%Vor%

Ich habe versucht, Breakpoints zu setzen und Anweisungen in dieser Methode zu drucken, und es scheint nie aktiviert zu sein. Ich würde vorschlagen, das Gleiche in Ihrem Code zu tun, da es sich anhört, als ob Ihr Problem mit meinem identisch ist. Ich habe im Beispiel gesucht und konnte keinen Ort finden, an dem die Methode manuell aufgerufen wurde. Ich habe bemerkt, dass Sie in Ihrem Code den Wert von passwordAuthenticationCompletion wie folgt initialisieren:

%Vor%

Es scheint so, als ob getPasswordAuthenticationDetails() aufgerufen werden soll, bevor diese Zeile in der Login-Methode den entsprechenden Wert verwendet: self.passwordAuthenticationCompletion.setResult(AWSCognitoIdentityPasswordAuthenticationDetails(username: emailTextField.text, password: passwordTextField.text))

Ich bin schon eine Weile festgefahren und versuche jetzt, weiter zu kommen, aber ich denke immer noch, dass dies der richtige Weg ist, um Benutzerregistrierung / -anmeldung zu implementieren. Es ist möglich, dass ein Teil des Codes in diesem Beispiel nicht sauber nach Swift übersetzt wird und daher einige wichtige Funktionen nicht ausgelöst werden. Ich werde weiter nachsehen und meine Antwort aktualisieren, wenn ich eine Lösung bestätige.

    
user3726962 15.06.2016 16:49
quelle
0

Ich habe die oben erwähnten Schritte mit Swift verfolgt und festgestellt, dass didCompletePasswordAuthenticationStepWithError niemals aufgerufen wird, obwohl LogInViewController erweitert AWSCognitoIdentityPasswordAuthentication .

Außerdem wird startPasswordAuthentication() nicht im Delegat aufgerufen, obwohl der Delegat auch AWSCognitoIdentityInteractiveAuthenticationDelegate implementiert.

Ich frage mich, ob dies ein Problem mit der Swift-Implementierung ist, da das Beispiel Objective-C, das Amazon bereitstellt, all diese Funktionen erfüllt.

    
user3349763 16.07.2016 22:58
quelle
0

Ich denke, da ist ein Problem:

Objekt-c - & gt;

%Vor%

Schnell - & gt; self.passwordAuthenticationCompletion.setResult(AWSCognitoIdentityPasswordAuthenticationDetails.init(username: username, password: password))

und da in der vorherigen Anweisung etwas nicht stimmt, wurde die Methode "didCompletePasswordAuthenticationStepWithError" nicht ausgelöst.

Ich habe viele Dinge ohne Glück versucht :(  - Ich habe versucht, alles in Swift umzusetzen (nicht Work)  - Ich habe versucht, die Objekt-C-Dateien meinem Swift-basierten Projekt (nicht Work) hinzuzufügen

Also, ich denke, ich werde das Original-Sample als Starter für mein Projekt verwenden.

Aktualisierung:

Ich implementiere den SignInViewController & amp; MFAController in Swift und importieren Sie diese Swift-Dateien in Object-C-basierte Projekte. und es ist gut in Ordnung! Also, jetzt bin ich mir sicher, dass es ein Problem oder Fehler gibt, wenn wir versuchen, "AWSCognitoIdentityPasswordAuthentication" & amp; & amp; "AWSCognitoIdentityMultiFactorAuthentication" -Protokolle im Swift-basierten Projekt. Die einzige Lösung, die ich gefunden habe, ist die Verwendung eines auf Object-C basierenden Projekts.

    
Alharbi 18.08.2016 08:23
quelle
0

So habe ich es in Swift gemacht, mit einem einzigen ViewController und ohne irgendetwas in AppDelegate einzurichten:

%Vor%     
Boris 14.09.2017 19:19
quelle