Hallo habr
In diesem Sommer hat Apple auf der WWDC-Konferenz 2019 ein eigenes Anmeldesystem
mit Apple- Berechtigung eingeführt und dieses für alle Anwendungen im App Store vorgeschrieben, die sich über soziale Medien anmelden. Die Ausnahme bilden Bildungs-, Unternehmens-, Regierungs- und Geschäftsanwendungen, die ihre eigene Berechtigung verwenden. Für die Anmeldung bei Apple hat Apple eine hochwertige
Dokumentation erstellt . In diesem Artikel wird anhand des CIAN-Beispiels beschrieben, wie diese in unserem Service implementiert wird.

Konfigurieren Sie das Apple-Entwicklerkonto
Die Integrationsarbeit beginnt mit der Einrichtung eines Entwicklerkontos. Zuerst müssen Sie die Option Mit Apple anmelden für Ihre App-ID aktivieren. Wechseln Sie dazu zur
Liste der Kennungen im Apple Developer Account , wählen Sie die erforderliche App-ID aus und aktivieren Sie die Option Mit Apple anmelden.
Jetzt konfigurieren wir die Service-ID - eine eindeutige Kennung für die Webanwendung, die Sie für den Zugriff auf die Anmeldung mit der Apple-API benötigen. Sie können bis zu 5 Service-IDs für eine einzelne App-ID erstellen. Klicken Sie dazu auf die Schaltfläche zum Erstellen von Kennungen, wählen Sie Service-ID, füllen Sie die erforderlichen Felder aus und klicken Sie im Feld Mit Apple anmelden auf Bearbeiten. Ein Formular wird geöffnet, in dem wir die richtige primäre App-ID auswählen, die Webdomäne angeben und die URLs für die Umleitung nach einer erfolgreichen Anmeldung auflisten. Beachten Sie, dass Sie nur 10 Rückgabe-URLs eingeben können:

Klicken Sie zum Speichern auf Speichern, Fortfahren und Registrieren. Ja, für Konfigurationsänderungen müssen Sie alle drei Schaltflächen anklicken, da die Änderungen sonst nicht wirksam werden.
Wählen Sie nun in der Liste Service ID den erstellten Bezeichner aus und klicken Sie im Feld Sign In With Apple erneut auf Edit. In dem sich öffnenden Fenster neben dem Feld für die Webadresse sehen wir zwei neue Schaltflächen:

Diese Datei ist erforderlich, damit Apple Ihre Ressource überprüfen kann. Laden Sie es herunter und platzieren Sie es in Ihrer Ressource. Diese Täuschung funktionierte für uns sofort nicht: Als unsere Administratoren die Datei hinzufügten, funktionierte die Weiterleitung (302) zu der Datei, die an anderer Stelle lag, auf der angegebenen URL, und Apple überprüfte sie nicht. Dann musste ich die Datei für den direkten Zugriff per URL platzieren (200). Nachdem Apple die Datei erfolgreich überprüft hat, leuchtet ein grünes Häkchen neben der Domäne auf:

Wechseln Sie im Abschnitt "Bezeichner" zum Abschnitt "Schlüssel" und erstellen Sie einen neuen Schlüssel. Aktivieren Sie dazu das Kontrollkästchen Mit Apple anmelden und klicken Sie zuerst auf Konfigurieren, um die App-ID zu überprüfen, und klicken Sie dann auf Weiter:

Laden Sie auf dem nächsten Bildschirm die Datei mit dem Schlüssel herunter und speichern Sie sie an einem sicheren Ort, da der Schlüssel nach dem Verlassen dieses Bildschirms nicht zum Herunterladen zur Verfügung steht. Auf derselben Seite sehen Sie die Schlüssel-ID, die wir noch benötigen:

Die Anmeldung bei Apple bietet Benutzern einen Bonus: Sie können eine gefälschte E-Mail-Adresse angeben, an die Sie nur von vertrauenswürdigen Adressen aus schreiben können. In diesem Fall ist eine zusätzliche Konfiguration erforderlich. Öffnen Sie den Abschnitt "Mehr", klicken Sie im Abschnitt "Mit Apple anmelden" auf "Konfigurieren" und geben Sie Ihre URL ein:

Fügen Sie der iOS-App die Schaltfläche Mit Apple anmelden hinzu.
CIAN arbeitet auf drei Plattformen: iOS, Android, Web. Es gibt ein natives SDK für iOS, daher sieht die Autorisierung folgendermaßen aus:

Um Anmelden mit Apple zur iOS-Anwendung hinzuzufügen, fügen Sie die Schaltfläche ASAuthorizationAppleIDButton hinzu und hängen Sie den Click-Handler daran:
let appleIDProvider = ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest() request.requestedScopes = [.fullName, .email] let authorizationController = ASAuthorizationController(authorizationRequests: [request]) authorizationController.delegate = self authorizationController.presentationContextProvider = self authorizationController.performRequests()
Beachten Sie neben ASAuthorizationAppleIDProvider auch ASAuthorizationPasswordProvider, mit dem Sie eine Reihe von "Login-Passwörtern" vom Schlüsselbund abrufen können.
Jetzt implementieren wir ASAuthorizationControllerPresentationContextProviding:
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { return self.view.window! }
Erstellen Sie einen ASAuthorizationControllerDelegate-Delegaten, der Erfolg oder Fehler meldet:
public func authorizationController( controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization ) { guard let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential, let code = appleIDCredential.authorizationCode, let codeStr = String(data: code, encoding: .utf8) else {
Wir senden den erhaltenen AuthorizationCode an den Server und warten auf eine Antwort vom Backend über den Erfolg der Autorisierung in unserem System.
Wir implementieren die Anmeldung mit Apple für Web und Android
Plötzlich stellt Apple für Android und das Internet kein SDK zur Verfügung. In beiden Fällen müssen Sie die Apple-Autorisierungsseite öffnen, und der Vorgang ist unterschiedlich:

Die URL für die Anmeldeseite lautet wie folgt:
https:
Betrachten Sie die Parameter:
- client_id - Service-ID, die oben registriert wurde.
- redirect_uri - Der URI, über den der Benutzer nach erfolgreicher Authentifizierung über die AppleID umgeleitet wird. Wir haben diesen URI oben beim Einrichten von Apple Developer angegeben.
- state - Die Sitzungskennung des Benutzers, die Apple zurückgibt, wenn redirect_uri aufgerufen wird, damit wir den Absender überprüfen können. Sie können eine Regel erfinden, um diesen Parameter selbst zu generieren, z. B. eine zufällige Zeichenfolge.
- scope - Dieser Parameter gibt an, welche Informationen vom Benutzer benötigt werden. Zum Beispiel Name, E-Mail oder beides, wie im obigen Beispiel.
- response_type - Dieser Parameter gibt an, in welcher Form die Antwort benötigt wird. Dies kann Code oder id_token sein. Wenn Sie id_token auswählen, müssen Sie es mit dem Parameter response_mode angeben, in dem Sie query, fragment und form_post angeben können.
Nach erfolgreicher Zwei-Faktor-Authentifizierung über appleID ruft Apple das angegebene redirect_uri auf und übergibt die Status- und Code-Parameter:
curl -X POST \ 'https:
Im Parameter code wird ein einmaliger Benutzerauthentifizierungscode übergeben, der 5 Minuten gültig ist. Im Parameter state die Sitzungskennung, die beim Erstellen des Berechtigungsformulars gesendet wurde, und im Parameter user die Benutzerdaten.
Datenabruf
Um Benutzerdaten auf allen Clients zu speichern, muss access_token von Apple abgerufen werden. Fordern Sie dazu zunächst den authorization_code an:
curl -X POST https:
In dieser Anfrage:
- Die client_id gibt die für die Webanwendung erstellte ServiceID und die AppID für die iOS-Anwendung an.
- Code - wir haben einen höheren Code nach der Weiterleitung erhalten oder ihn vom iOS-Client übertragen
- Im Parameter grant_type übergeben wir den Zweck des Abrufs des Tokens: Autorisierung (authorization_code) oder Erneuerung des Tokens (refresh_token).
- im Parameter client_secret - JSON-Web-Token basierend auf dem geheimen Schlüssel, der während der Anwendungsregistrierung abgerufen wurde.
Sie können JSON-Web-Token in Python erstellen:
claims = { 'iss': APPLEID_TEAM_ID, 'aud': 'https://appleid.apple.com', 'sub': client_id, 'iat': current_timestamp, 'exp': current_timestamp + expire_period, } headers = {'kid': 'APPLEID_KEY_ID', 'alg': 'ES256'} client_secret = jwt.encode(payload=claims, key=secret_key, algorithm='ES256', headers=headers).decode('utf-8')
Wenn alles gut gegangen ist, werden die folgenden Parameter in der Antwort kommen:
{ "access_token":"ufhzch", "token_type":"Bearer", "expires_in":3600, "refresh_token":"some_refresh_token", "id_token":"some_long_signed_jwt_token" }
Hurra, hier ist access_token. Dazu kommt refresh_token, das bei Bedarf aktualisiert werden kann access_token.
Benutzerinformationen werden im Feld id_token gespeichert, müssen jedoch dekodiert werden:
public_key = jwt.algorithms.RSAAlgorithm.from_jwk( json.dumps(apple_public_key) ) data = jwt.decode( id_token, public_key, algorithm="RS256", verify=True, audience=client_id, )
Apple_public_key ist ein öffentlicher Schlüssel, der über den
Link abgerufen werden kann
.Nach der Dekodierung erhalten wir:
data = { "iss": "https://appleid.apple.com", "aud": client_id, "exp": 1570379521, "iat": 1570378921, "sub": " ", "at_hash": "8ZDF6j786IQf9mA", "email": "someemail@gmail.com", "email_verified": "true", "auth_time": 1570378804 }
Die E-Mail wird nur einmal gesendet, wenn sich der Benutzer zum ersten Mal über Bei Apple anmelden bei Ihrem Dienst anmeldet. Beim nächsten Mal überträgt Apple diese Daten nur, wenn der Benutzer die Bindung Ihrer Anwendung selbst aufhebt. Diese Autorisierung von Apple unterscheidet sich von anderen Diensten, bei denen Daten über die API abgerufen werden können, und es wurden keine Informationen gefunden, die eine solche Implementierung vorsehen.
In dieser Antwort benötigen wir die Subparameter, die jedes Mal gesendet werden, und eine E-Mail, also speichern wir sie in unserem System und informieren den Kunden über die erfolgreiche Autorisierung. GEWINN.
Erste Ergebnisse
Nach der Veröffentlichung der neuen Version von CIAN with Sign in with Apple entfiel am ersten Tag des Tages ein Drittel der Neuanmeldungen für iOS 13 auf CIAN und steht nun für alle iOS-Versionen an zweiter Stelle nach VK. Es gibt nur wenige Registrierungen auf der Website, die AppleID verwenden, aber ihre Anzahl wächst langsam. Und jetzt haben wir vor, die Autorisierung über AppleID für Android-Anwendungen zu aktivieren und zu sehen, wie viele Benutzer sich auf solch knifflige Weise registrieren werden.