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.
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.
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.
Die AWS-Beispiel-App ist nicht einfach, aber sie ist wirklich einfach.
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?
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?
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.
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:
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.
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.
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.
Tags und Links ios amazon-web-services amazon-cognito