Deutsch
  • SDK
  • OIDC

Implementieren Sie ein einfaches Client-seitiges OIDC SDK

Logto bietet eine Vielzahl von SDKs für verschiedene Plattformen. Neben unseren offiziellen SDKs ermutigen wir Entwickler aus der Community, ihre eigenen benutzerfreundlichen SDKs zu erstellen. Dieser Artikel wird Sie beim Aufbau eines grundlegenden Client-seitigen SDKs für OIDC anleiten.

Simeng
Simeng
Developer

Einführung

Logto bietet unseren Entwicklern und Geschäftsgruppen eine umfassende Lösung für Customer Identity und Access Management (CIAM). Wir bieten eine breite Palette von fertigen SDKs für verschiedene Plattformen und Anwendungs-Frameworks. In Verbindung mit unserem Logto Cloud Service können Sie in wenigen Minuten einen hochsicheren Benutzer-Autorisierungsfluss für Ihre Anwendung einrichten. Als ein Unternehmen, das aus der Entwickler-Community hervorgegangen ist, schätzt und fördert Logto unser Community-Engagement. Zusätzlich zu den offiziell entwickelten Logto-SDKs ermutigen wir kontinuierlich und heißen Entwickler aus der Community willkommen, ihre Expertise durch die Erstellung von vielfältigeren und benutzerfreundlicheren SDKs einzubringen, um die einzigartigen Bedürfnisse verschiedener Plattformen und Frameworks zu erfüllen. In diesem Artikel werden wir kurz demonstrieren, wie man Schritt für Schritt ein OIDC-Standard Auth-SDK implementiert.

Kontext

Der OpenID Connect (OIDC) Flow ist ein Authentifizierungsprotokoll, das auf dem OAuth 2.0 Framework aufbaut, um Identitätsüberprüfung und Single Sign-On-Funktionalität zu bieten. Es ermöglicht Benutzern, sich bei einer Anwendung zu authentifizieren und sicher eine weitere Zugangsberechtigung für private Ressourcen zu erhalten. Bitte beziehen Sie sich auf die OIDC-Spezifikationen für weitere Details.

Workflow

Ein Standard-Autorisierungscode-Flow beinhaltet folgende Schritte:

Authentifizierungsfluss

  1. Benutzer initiiert die Anmeldeanforderung: Ein anonymer Benutzer kommt zu Ihrer Anwendung von einem öffentlichen Eingang. Versucht, sich zu authentifizieren und eventuell weiteren Zugang zu einer geschützten Ressource auf einer Drittanbieteranwendung oder -dienst zu erhalten.
  2. Benutzerauthentifizierung: Die Client-App generiert eine Authentifizierungs-URI und sendet eine Anforderung an den Autorisierungsserver, der den Benutzer zu seiner Anmeldeseite umleitet. Der Benutzer interagiert mit der Anmeldeseite mit einer Vielzahl von Anmeldemethoden und wird vom Autorisierungsserver authentifiziert.
  3. Rückmeldung nach der Anmeldung handhaben: Nach einer erfolgreichen Authentifizierung wird der Benutzer zurück zu Ihrer Anwendung mit einem gewährten authorization_code umgeleitet. Dieser authorization_code enthält alle relevanten Berechtigungen, die mit dem Authentifizierungsstatus und den angeforderten Autorisierungsdaten verknüpft sind.
  4. Token-Austausch: Anforderung zum Token-Austausch mit dem authorization_code, der aus der obigen Weiterleitungsadresse extrahiert wurde. Im Gegenzug:
    • id_token: Ein digital signiertes JWT, das Identitätsinformationen über den authentifizierten Benutzer enthält.
    • access_token: Ein opakes access_token, das zur Zugriff auf den Benutzer-Basisinfo-Endpunkt verwendet werden kann.
    • refresh_token: Berechtigungs-Token, das dem Benutzer einen kontinuierlichen Austausch für ein access_token ermöglicht.

Autorisierungsfluss

  1. Zugriff auf Benutzerinformationen: Um mehr Benutzerinformationen zugreifen zu können, kann die Anwendung zusätzliche Anfragen an den UserInfo-Endpunkt stellen, indem sie den opaken access_token verwendet, der aus dem anfänglichen Token-Austauschfluss erhalten wurde. Dies ermöglicht die Abrufung zusätzlicher Details über den Benutzer, wie seine E-Mail-Adresse oder sein Profilbild.
  2. Gewährung des Zugriffs auf die geschützte Ressource: Bei Bedarf kann die Anwendung zusätzliche Anfragen an den Token-Austausch-Endpunkt stellen, indem sie das refresh_token zusammen mit resource und scope-Parametern verwendet, um ein spezielles access_token für den Benutzer zum Zugriff auf die Zielressource zu erhalten. Dieser Prozess führt zur Ausstellung eines JWT-formatierten access_token, der alle notwendigen Autorisierungsinformationen enthält, um auf die geschützte Ressource zuzugreifen.

Implementierung

Wir werden einige Designstrategien innerhalb unseres @logto/client JavaScript SDK verfolgen, um den Prozess der Implementierung eines einfachen SDK für Ihre eigene Client-Anwendung zu demonstrieren. Bitte beachten Sie, dass die detaillierte Code-Struktur je nach dem Client-Framework, mit dem Sie arbeiten, variieren kann. Sie können frei wählen, eines der offiziellen Logto-SDKs als Beispiel für Ihr eigenes SDK-Projekt zu verwenden.

Vorschau

Konstruktor

Der Konstruktor sollte ein logtoConfig als Eingabe erhalten. Dies liefert alle notwendigen Konfigurationen, die Sie benötigen, um eine Auth-Verbindung über dieses SDK herzustellen.

Je nach Plattform oder Framework, das Sie für das SDK verwenden, können Sie eine beständige lokale Speicherinstanz an den Konstruktor übergeben. Diese Speicherinstanz wird verwendet, um alle autorisierungsbezogenen Tokens und Secrets zu speichern.

Benutzerauthentifizierung initialisieren

Bevor eine Authentifizierungsanforderungs-URL generiert wird, ist es unerlässlich, mehrere Vorbereitungsschritte durchzuführen, um einen sicheren Prozess zu gewährleisten.

Erhalt der OIDC-Konfigurationen vom Autorisierungsserver

Definieren Sie eine private Methode getOidcConfigs zum Abrufen der OIDC-Konfigurationen vom Discovery-Endpunkt des Autorisierungsservers. Die OIDC-Konfigurationsantwort enthält alle Metadateninformationen, die der Client zur Interaktion mit dem Autorisierungsserver verwenden kann, einschließlich seiner Endpunktstandorte und der Fähigkeiten des Servers. (Bitte beziehen Sie sich auf OAuth OAuth Authorization Server Metadata Specs für mehr Details.)

PKCE-Generator

Ein PKCE(Proof Key for Code Exchange) Validierungsfluss ist unerlässlich für alle Autorisierungscode-Austauschflüsse für öffentliche Clients. Er mindert das Risiko des Angriffs auf den Autorisierungscode. Daher sind für alle Autorisierungsanfragen von öffentlichen Client-Anwendungen (z. B. native App und SPA) ein code_challenge und code_verifier erforderlich.

Die Implementierungsmethoden können je nach den Sprachen und Frameworks, die Sie verwenden, variieren. Bitte beziehen Sie sich auf die Spezifikation von code_challenge und code_verifier für die detaillierten Definitionen.

Generieren des State-Parameters

Im Autorisierungsfluss ist der state-Parameter ein zufällig generierter Wert, der in der Autorisierungsanforderung enthalten ist, die vom Client gesendet wird. Er dient als Sicherheitsmaßnahme gegen Cross-Site-Request-Forgery (CSRF)-Angriffe.

Zwischenspeicherung von Sitzungsinformationen

Es gibt mehrere Parameter, die in dem Speicher zur Validierung nach der Authentifizierung des Benutzers und der Weiterleitung zurück zur Clientseite aufbewahrt werden müssen. Wir werden eine Methode implementieren, um diese Zwischenparameter im Speicher zu setzen.

Anmelden

Fassen wir alles, was wir bisher implementiert haben, zusammen, definieren wir eine Methode, die eine Benutzer-Anmeldungs-URL generiert und den Benutzer zum Autorisierungsserver umleitet, um sich zu authentifizieren.

Bearbeitung des Benutzeranmelde-Callbacks

Im vorherigen Abschnitt haben wir eine Methode zur Anmeldung erstellt, die eine URL für die Benutzerauthentifizierung generiert. Diese URL enthält alle erforderlichen Parameter, um einen Authentisierungsfluss von einer Clientanwendung zu starten. Die Methode leitet den Benutzer zur Anmeldeseite des Autorisierungsservers zur Authentifizierung um. Nach erfolgreicher Anmeldung wird der Endbenutzer an den oben angegebenen Redirect_uri-Standort umgeleitet. Alle notwendigen Parameter werden in der Redirect_uri übertragen, um die folgenden Token-Austausch-Flüsse abzuschließen.

Extrahieren und Verifizieren der Callback-URL

Dieser Validierungsschritt ist äußerst wichtig, um jegliche Formen von gefälschten Autorisierungs-Callback-Angriffen zu verhindern. Die Callback-URL MUSS sorgfältig verifiziert werden, bevor eine weitere Code-Austauschanforderung an den Autorisierungsserver gesendet wird. Zunächst müssen wir die signInSession-Daten, die wir aus dem App-Speicher abgerufen haben.

Überprüfen Sie dann die Parameter der Callback-URL, bevor Sie die Token-Austauschanforderung senden.

  • Verwenden Sie die zuvor gespeicherte redirectUri, um zu überprüfen, ob die callbackUri die gleiche ist wie die, die wir an den Autorisierungsserver gesendet haben.
  • Verwenden Sie den zuvor gespeicherten state, um zu überprüfen, ob der zurückgegebene State derselbe ist wie der, den wir an den Autorisierungsserver gesendet haben.
  • Prüfen Sie, ob vom Autorisierungsserver ein Fehler zurückgegeben wird
  • Überprüfen Sie die Existenz des zurückgegebenen authorization_code

Senden der Code-Austauschanforderung

Als letzter Schritt des Benutzerauthentifizierungsflusses verwenden wir den zurückgegebenen authorization_code, um eine Token-Austauschanforderung zu senden und die erforderlichen Autorisierungstoken zu erhalten. Für weitere Details zu den Definitionen der Anforderungsparameter verweisen Sie bitte auf die Token-Austauschspezifikation.

  • code: der authorization_code, den wir aus der Callback-URI erhalten haben
  • clientId: die Anwendungs-ID
  • redirectUri: Der gleiche Wert, der bei der Generierung der Anmelde-URL für den Benutzer verwendet wurde.
  • codeVerifier: PKCE-Code-Verifizierer. Ähnlich wie bei der redirectUri wird der Autorisierungsserver diesen Wert mit dem, den wir zuvor gesendet haben, vergleichen und so die Validierung der eingehenden Token-Austauschanforderung sicherstellen.

Bearbeiten des Anmelde-Callbacks

Fassen wir alles zusammen, was wir haben. Lassen Sie uns die Methode zur Behandlung des Anmelde-Callbacks erstellen:

Als Ergebnis wird die Token-Austauschanforderung folgende Token zurückgeben:

  • id_token: OIDC idToken, ein JSON Web Token (JWT), das Identitätsinformationen über den authentifizierten Benutzer enthält. id_token kann auch als Single Source of Truth(SSOT) des Authentifizierungsstatus eines Benutzers verwendet werden.
  • access_token: Der standardmäßig vom Autorisierungsserver zurückgegebene Autorisierungscode. Kann zur Aufruf des Benutzerinfo-Endpunkts und zur Abrufung von Informationen über authentifi zierte Benutzer verwendet werden.
  • refresh_token: (wenn offline_access scope in der Autorisierungsanforderung vorhanden ist): Dieses Aktualisierungs-Token ermöglicht es der Clientanwendung, ohne erneute Authentifizierung des Benutzers ein neues Zugangs-Token zu erhalten und somit einen längerfristigen Zugang zu den Ressourcen zu gewähren.
  • expires_in: Die Dauer in Sekunden, während der das Zugangs-Token gültig ist, bevor es abläuft.

ID-Token-Überprüfung

Die Überprüfung und Extraktion von Ansprüchen aus dem id_token ist ein entscheidender Schritt im Authentifizierungsprozess, um die Authentizität und Integrität des Tokens zu gewährleisten. Hier sind die Schlüsselschritte, die an der Überprüfung eines idToken beteiligt sind.

  • Signaturüberprüfung: Das id_token ist digital signiert durch den Autorisierungsserver mit seinem privaten Schlüssel. Die Client-Anwendung muss die Signatur mit dem öffentlichen Schlüssel des Autorisierungsservers validieren. Dies stellt sicher, dass das Token nicht manipuliert wurde und tatsächlich vom legitimen Autorisierungsserver ausgestellt wurde.
  • Überprüfung des Ausstellers**:** Überprüfen Sie, ob die "iss" (Aussteller)-Anspruch im id_token dem erwarteten Wert entspricht, was darauf hinweist, dass das Token von dem richtigen Autorisierungsserver ausgestellt wurde.
  • Überprüfung des Zielpublikums: Stellen Sie sicher, dass der "aud" (Zielpublikum)-Anspruch im id_token mit der Client-ID der Clientanwendung übereinstimmt, um sicherzustellen, dass das Token für den Client bestimmt ist.
  • Ablaufprüfung: Überprüfen Sie, ob der "iat" (ausgestellt um) Anspruch im id_token nicht die aktuelle Zeit überschritten hat, um sicherzustellen, dass das Token noch gültig ist. Da es Netzwerktransaktionskosten gibt, müssen wir eine ausgegebene Zeitduldung festlegen, wenn wir den erhaltenden iat-Anspruch des Tokens validieren.

Das zurückgegebene id_token ist ein standardisiertes JSON Web Token (JWT). Je nachdem, welches Framework Sie verwenden, finden Sie verschiedene praktische JWT-Token-Validierungs-Plugins, die Ihnen bei der Dekodierung und Validierung des Tokens helfen können. Für dieses Beispiel werden wir jose in unserem JavaScript SDK verwenden, um die Token-Validierung und Dekodierung zu erleichtern.

Benutzerinformationen abrufen

Nach erfolgreicher Benutzerauthentifizierung können grundlegende Benutzerinformationen aus dem vom Autorisierungsserver ausgestellten OIDC id_token abgerufen werden. Aufgrund von Leistungsüberlegungen ist der Inhalt des JWT-Tokens jedoch begrenzt. Um detailliertere Benutzerprofilinformationen zu erhalten, bieten OIDC-konforme Autorisierungsserver einen out-of-the-box-Benutzerinformations-Endpunkt an. Dieser Endpunkt ermöglicht es Ihnen, durch Anforderung spezifischer Benutzerprofilbereiche zusätzliche Benutzerprofildaten abzurufen.

Bei einem Aufruf eines Token-Austausch-Endpunkts ohne Angabe einer spezifischen API-Ressource wird der Autorisierungsserver standardmäßig ein undurchsichtiges access_token ausgeben. Dieses access_token kann nur zur Zugriff auf den Benutzerinfo-Endpunkt verwendet werden, um grundlegende Benutzerprofilinformationen abzurufen.

Zugangs-Token für geschützte Ressourcenautorisierung abrufen

In den meisten Fällen benötigt eine Client-Anwendung nicht nur Benutzerauthentifizierung, sondern auch Benutzerberechtigung zum Zugriff auf bestimmte geschützte Ressourcen oder API-Endpunkte. Hier werden wir das refresh_token, das während der Anmeldung erhalten wurde, verwenden, um access_token(s) zu erwerben, die speziell zur Verwaltung bestimmter Ressourcen gewährt wurden. Dies ermöglicht uns den Zugriff auf diese geschützten APIs.

Zusammenfassung

Wir haben wesentliche Methoden-Implementierungen für den Benutzerauthentifizierungs- und Berechtigungsprozess der Client-Seite-App bereitgestellt. Je nach speziellem Szenario können Sie die SDK-Logik entsprechend organisieren und optimieren. Bitte beachten Sie, dass es aufgrund unterschiedlicher Plattformen und Frameworks Variationen geben kann.

Für weitere Details erkunden Sie die SDK-Pakete, die von Logto angeboten werden. Wir möchten mehr Benutzer einladen, sich der Entwicklung anzuschließen und mit uns Diskussionen zu führen. Ihr Feedback und Ihre Beiträge sind sehr geschätzt, während wir die Fähigkeiten des SDKs weiter ausbauen und erweitern.

Anhang

Reservierte Bereiche

Logto-reservierte Bereiche, die Sie während der anfänglichen Auth-Anforderung übergeben müssen. Diese Bereiche sind entweder OIDC-reservierte oder Logto-reservierte grundlegende Bereiche, um einen erfolgreichen Autorisierungsfluss abzuschließen.

Name des BereichsBeschreibung
openidErforderlich für die Gewährung von id_token nach einer erfolgreichen Authentifizierung.
offline-accessErforderlich für die Gewährung eines refresh_token, das Ihrer Clientanwendung den Austausch und die Erneuerung eines Zugangs-Tokens ohne Benutzerauthentifizierung ermöglicht.
profileErforderlich für den Zugriff auf die Grundinformationen des Benutzers

Logto Config

EigenschaftsnameTypErforderlichBeschreibungStandardwert
appIdZeichenkettewahrDie einzigartige Anwendungsidentifikation. Vom Autorisierungsserver generiert, um die Client-Anwendung zu identifizieren.
appSecretZeichenketteDas Anwendungssecret wird zusammen mit der Anwendungs-ID verwendet, um die Identität des Anfragenden zu überprüfen. Es ist erforderlich für vertrauliche Clients wie Go Web oder Next.js Web Apps und optional für öffentliche Clients wie native oder Single-Page-Anwendungen (SPAs).
endpointZeichenkettewahrIhr Endpunkt des Autorisierungsservers. Diese Eigenschaft wird häufig verwendet, um Autorisierungsanforderungen zu generieren.ENDPUNKT.
BereicheZeichenkettenlisteGibt alle notwendigen Ressourcenbereiche an, die der Benutzer benötigen könnte, um Zugang zu bestimmten geschützten Ressourcen zu erhalten.[reservedScopes]
RessourcenZeichenkettenlisteAlle geschützten Ressourcenindikatoren, auf die der Benutzer möglicherweise Zugriff anfordern wird.

Nutzen Sie Methoden

generateRandomString