Blog

Wie Google hat auch Apple ein Authentifizierungssystem namens Sign in With Apple eingeführt.

Das bedeutet, dass Benutzer, die eine Apple ID haben, sich mit ihren bestehenden Anmeldedaten bei einem Web- oder App-Dienst anmelden können.

Dieser Artikel wird Ihnen helfen, das Sign in With Apple Feature zu verstehen und in Ihre Symfony Anwendung zu implementieren.

Für wen ist dieser Artikel gedacht?

Dieser Artikel richtet sich an PHP-Backend-Entwickler. Er wurde für das Symfony-Framework geschrieben, kann aber auch für andere Frameworks verwendet werden (mit einigen Änderungen).

Dieser Artikel ist nicht für Anfänger gedacht und wird nicht das grundlegende Setup von Symfony erklären. Um mehr über Symfony zu erfahren, finden Sie die Symfony-Dokumentation hier.

Was Sie wissen müssen:

1. PHP OOP

2. Symfony

Vorteile der Apple Sign in-Authentifizierung

Neben der Nutzung der bestehenden UI des Login-Dienstleisters haben Benutzer nun die Möglichkeit, sich „privat“ bei einem Dienst anzumelden.

Das bedeutet, dass Apple die echte Benutzer-E-Mail versteckt und eine neue generiert, die in einem Dienst verwendet werden muss.

Dies wird auch verhindern, dass Tracker von anderen Plattformen verfolgen können, welche Art von Apps oder Diensten Sie verwenden.

Wenn Sie ein Apple-Gerät verwenden, kann die Anmeldung über Touch ID oder Face ID erfolgen, was eine schnellere Möglichkeit der Anmeldung darstellt.

Ist die Anmeldung mit Apple obligatorisch?

Wenn Sie es mit einer API zu tun haben, die eine Authentifizierung von iOS-Geräten erfordert, dann lautet die Antwort ja.

An diesem Punkt zwingt Apple seine neuen oder bestehenden Apps, die irgendeine Art von „Sign in“ Funktion haben, auch Sign in with Apple zu implementieren.

Wie Sign In with Apple funktioniert:

Die serverseitige Authentifizierung ist sehr einfach zu verstehen, da der größte Teil der Arbeit auf der Seite der Client App liegt. Die Client-App (mobile oder Frontend-App) verbindet sich mit einem Apple-Server und sendet die E-Mail und das Passwort des Benutzers. In diesem Schritt wird der Benutzer gefragt, ob er seine E-Mail verbergen möchte.

Apple sendet dann die Benutzerdaten an die Client-App zurück und diese Daten werden an den Server gesendet. Das Wichtigste dabei ist der authorization_code.

Was der Server tatsächlich tut, ist zu überprüfen, dass der authotization_code gültig ist und dass der Benutzer existiert.

Da der Benutzer seine E-Mail verstecken kann, müssen wir uns darüber im Klaren sein, dass wir die echten Daten des Benutzers nicht bekommen – außer in dem Fall, wenn die echten Daten notwendig sind und wir den Benutzer später danach fragen.

Schritte:

  1. Die App sendet uns einen authorization_code an den Backend-Server
  2. Backend-Server stellt eine Anfrage an einen Apple-Server
  3. Apple-Server gibt eine Antwort zurück

Voraussetzungen:

  • Die Anmeldedaten von Apple Connect: Apple Connect ist ein Apple-Dienst für den Umgang mit iOS-Apps. Dort können wir alle Anmeldeinformationen erhalten, die benötigt werden, um Apple mitzuteilen, dass wir autorisiert sind, den authorization_code des Benutzers zu überprüfen.
  • Apple ID speichern – diese wird benötigt, um den Benutzer für die Anmeldung zu finden.
  • patrickbussamann/oauth2-apple – Bibliothek, die den größten Teil der Logik für uns erledigen wird

Hinweis!

Sie erhalten die Benutzer-E-Mail nur bei der Registrierung, später beim Login wird nur die ID in der Antwort angezeigt.

Apple Credentials und wo man sie findet

Die Credentials finden Sie im Apple Cloud Account, aber als Backend-Entwickler können Sie normalerweise einfach jemanden aus dem Mobile-Team bitten, Ihnen diese zu geben. Andernfalls, wenn Sie Zugriff auf den App Store Connect für die App haben, finden Sie die Credentials unter Ihren App-Einstellungen.

Sie werden benötigt:

  1. Apple Key ID https://developer.apple.com/account/resources/authkeys/list
  2. Apple Team ID https://developer.apple.com/account/#/membership/
  3. Apple Client ID – Dies ist Ihre Client ID
  4. Key File Path -> Sie müssen die Datei auf https://developer.apple.com/account/resources/authkeys/list herunterladen und den Pfad zu dieser Datei angeben

Es ist wichtig, dass Sie auf der Seite Certificates, Identifiers & Profiles das Sign in with Apple aktivieren.

Wir haben die Anmeldedaten für unsere App in der .env Datei unseres Projekts abgelegt:

Das Hinzufügen der Apple ID zur Datenbank ist in Symphony recht einfach. Wenn Sie eine klassische MVC-Architektur verwenden, verwenden Sie einfach maker und fügen Sie das Feld zu einer Entität hinzu (normalerweise zur Entität User, aber wenn Sie eine andere Entität haben, in der Sie diese Art von Daten speichern, ist das auch ok).

Installieren der oauth2-apple-Bibliothek in der App:

Dies erfordert nur einen Schritt:

  1. Geben Sie composer require patrickbussamann/oauth2-apple in Ihr Terminal ein

Dies wird ein Paket installieren, das alles enthält, was Sie für die Verifizierung mit dem user authorization code benötigen.

Implementierung des PHP-Teils

Wir verwenden hier das Factory Method Design Pattern. Um mehr über dieses Entwurfsmuster zu erfahren, folgen Sie diesem Link.

In Factory werden wir unseren Provider erstellen, der die Anfrage für uns bearbeiten wird.In diesem Teil müssen wir die Apple Credentials an den Konstruktor des Providers übergeben.

class AppleProviderFactory
{
    private const FILE_CREDENTIALS_PATH = 'path/to/key/file;

    /**
     * @param string $clientId
     * @param string $teamId
     * @param string $keyFileId
     * @param string $redirectUrl
     * @return Apple
     * @throws Exception
     */
    public static function createProvider(
        string $clientId,
        string $teamId,
        string $keyFileId,
        string $redirectUrl
    ): Apple {
        return  new Apple([
            'clientId'          => $clientId,
            'teamId'            => $teamId, //https://developer.apple.com/account/#/membership/ (Team ID)
            'keyFileId'         => $keyFileId, //https://developer.apple.com/account/resources/authkeys/list (Key ID)
            'keyFilePath'       => self::FILE_CREDENTIALS_PATH, //__DIR__ . '/AuthKey_template.p8'->Download key above
            'redirectUri'      => $redirectUrl //The destination URI the code was originally sent to.
        ]);
    }
}

Apple Authenticator ist unsere Klasse, die die Logik zum Abrufen der Benutzerdaten enthält.

Es ist wichtig, die Logik in eine „try catch“-Methode zu verpacken und Fehler selbst zu behandeln.

Wenn die Verifizierung fehlschlägt, erhalten Sie einen Apple response code, den Sie googeln können, um die Lösung zu finden.  

Der problematischste Teil ist, dass der authorization_code einen Zeitrahmen hat und nur einmal verwendet werden kann, daher ist es gut, einen iOS- oder einen Frontend-Dev in Bereitschaft zu haben, wenn Sie dies implementieren werden.

class AppleAuthenticator
{
    private const AUTHORIZATION_CODE_NAME_REFERENCE = 'authorization_code';
    private const CODE_NAME_REFERENCE = 'code';
    /**
     *
@var Apple
    
*/
   
private Apple $provider;

    /**
     * AppleAuthenticator constructor.
     *
@param Apple $provider
     */
   
public function __construct(Apple $provider)
    {
        $this->provider = $provider;
    }


    /**
     *
@param string $authorisationCode
     *
@return ResourceOwnerInterface
    
* @throws AppleServerException
    
*/
   
public function getUserData(string $authorisationCode): ResourceOwnerInterface
    {
        try {
            /** @var AccessToken $token */
           
$token = $this->provider->getAccessToken(self::AUTHORIZATION_CODE_NAME_REFERENCE, [
                self::CODE_NAME_REFERENCE => $authorisationCode
            ]);

            $user = $this->provider->getResourceOwner($token);
        } catch (Exception $exception) {
            throw new AppleServerException($exception);
        }

        return $user;
    }
}
class AppleAuthenticationService
{
    /**
     *
@var string
     */
    private string
$clientId;

    /**
     *
@var string
     */
    private string
$teamId;

    /**
     *
@var string
     */
    private string
$appleKeyId;

    /**
     * AuthenticationService constructor.
     *
@param string $clientId
     *
@param string $teamId
     *
@param string $appleKeyId
     */
    public function
__construct(
        string $clientId,
        string $teamId,
        string $appleKeyId
    ) {
        $this->clientId = $clientId;
        $this->teamId = $teamId;
        $this->appleKeyId = $appleKeyId;
    }

    /**
     *
@param string $authorizationCode
     *
@param string $redirectUrl
     *
@return ResourceOwnerInterface
     *
@throws AppleServerException
     */
    public function
authenticate(string $authorizationCode, string $redirectUrl): ResourceOwnerInterface
    {               //create provider
        $applePrpvider = AppleProviderFactory::createProvider(
            $this->clientId,
            $this->teamId,
            $this->keyFileId,
            $redirectUrl
        );
        // pass provider and authorization_code to Authenticator and get users data

In Ihrem handler, mit dem autowiring, können Sie auf den authentication service wie folgt zugreifen:

/**
 *
@var AppleAuthenticationService
 
*/
private AppleAuthenticationService $authenticationService;
/**

 * CreateAppleUserHandler constructor.

 * @param AppleAuthenticationService $authenticationService

 */

public function __construct(

    AppleAuthenticationService $authenticationService

) {

    $this->authenticationService = $authenticationService;

} 
$user = $this->authenticationService->authenticate(
    'auth_code'
    'redirect_url'
);

Um die Anmeldung und den Login etwas einfacher zu gestalten, wählen wir, dem Benutzer unser JWT-Authentifizierungs-Token als Antwort zurückzugeben.  

Fazit

Sign in With Apple ist eine sichere und schnelle Möglichkeit für iOS-Benutzer, sich anzumelden und Dienste zu nutzen, die eine Authentifizierung erfordern.

Man geht davon aus, dass es im Laufe der Zeit neben dem Web-Login von Google und Facebook üblich sein wird.

Es ist ziemlich einfach, dies zu implementieren, sobald Sie wissen, wie es funktioniert.

Dieser Artikel hat Schritt für Schritt erklärt, wie es funktioniert, so dass alles für Sie klappen sollte. Denken Sie nur an folgende Punkte:

  1. Die E-Mail kann privat sein
  2. Die E-Mail wird nur beim ersten Mal angezeigt
  3. Der Authorization_code hat einen Zeitrahmen, in dem es funktioniert

Happy Coding!