Zum Hauptinhalt springen

Device flow: Auth mit Logto

hinweis:

Diese Anleitung setzt voraus, dass du eine Anwendung vom Typ „Native“ mit Device Flow als Autorisierungsflow in der Logto-Konsole erstellt hast.

Einführung

Der OAuth 2.0 Device Authorization Grant (Device Flow) ist für Geräte mit eingeschränkten Eingabemöglichkeiten konzipiert, wie Smart-TVs, Spielkonsolen, CLI-Tools und IoT-Geräte. Er ermöglicht es Benutzern, den Anmeldeprozess auf dem Gerät zu starten, aber die Authentifizierung auf einem separaten Gerät mit Browser, wie einem Telefon oder Laptop, abzuschließen.

Da das Gerät selbst keinen browserbasierten Anmeldeflow durchführen kann, zeigt das Gerät einen kurzen Code und eine URL an. Der Benutzer besucht diese URL auf einem anderen Gerät, gibt den Code ein und meldet sich an. In der Zwischenzeit fragt das ursprüngliche Gerät Logto ab, bis die Autorisierung abgeschlossen ist.

Anwendungs-Credentials abrufen

Navigiere in deiner Logto-Konsole zur Detailseite deiner Anwendung, um die folgenden Zugangsdaten zu erhalten:

  • App ID: Die eindeutige Kennung deiner Anwendung (auch bekannt als client_id).
  • Logto-Endpunkt: Dein Logto-Autorisierungsserver-Endpunkt. Du findest ihn in der Logto-Konsole unter „Anwendungsdetails“.

Für Logto Cloud lautet der Endpunkt https://{your-tenant-id}.logto.app.

hinweis:

Device Flow Apps sind öffentliche Clients, daher ist kein App Secret erforderlich.

Device Code anfordern

Starte den Device Flow, indem du eine POST-Anfrage an den Device Authorization Endpoint sendest:

curl --request POST 'https://your.logto.endpoint/oidc/device/auth' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=your-application-id' \
--data-urlencode 'scope=openid offline_access profile'

Die Antwort enthält:

FeldBeschreibung
device_codeEin eindeutiger Code, den deine App beim Polling des Token-Endpunkts verwendet.
user_codeEin kurzer Code, der dem Benutzer angezeigt wird, damit er ihn im Browser eingibt.
verification_uriDie URL, bei der der Benutzer den user_code eingibt.
verification_uri_completeEine URL mit vorausgefülltem user_code. Benutzer können diese URL direkt besuchen, um die manuelle Codeeingabe zu überspringen — du kannst sie als QR-Code, Link oder anders präsentieren.
expires_inDie Lebensdauer in Sekunden von device_code und user_code. Nach Ablauf nicht mehr weiter abfragen.

Zeige die Verifizierungs-URL dem Benutzer an

Zeige den user_code und die verification_uri auf dem Bildschirm deines Geräts an.

Alternativ kannst du verification_uri_complete verwenden, bei dem der Code bereits vorausgefüllt ist — der Benutzer muss nur noch bestätigen. Wie du es präsentierst, bleibt dir überlassen: QR-Code, klickbarer Link usw.

Abfrage nach Tokens

Während der Benutzer die Authentifizierung im Browser abschließt, sollte dein Gerät den Token-Endpunkt abfragen. Deine App sollte mindestens 5 Sekunden zwischen den Abfragen warten:

curl --request POST 'https://your.logto.endpoint/oidc/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=your-application-id' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
--data-urlencode 'device_code=DEVICE_CODE'

Ersetze DEVICE_CODE durch den Wert device_code aus der Device Authorization Antwort.

Beende das Polling, wenn:

  • Du eine erfolgreiche Token-Antwort erhältst.
  • Die expires_in-Zeit aus der Device Code Antwort abgelaufen ist.
  • Du einen nicht wiederholbaren Fehler wie expired_token oder access_denied erhältst.

Token-Antwort

Nachdem der Benutzer zugestimmt hat, enthält die Antwort:

FeldBeschreibung
access_tokenDas Zugangstoken (Access token). Dies ist standardmäßig eine opake Zeichenkette; wenn ein resource angefordert wird, ist es ein JWT mit aud auf die Ressourcen-URI gesetzt.
id_tokenDas ID-Token (ID token) mit Benutzeridentitätsansprüchen. Nur vorhanden, wenn der openid Scope angefordert wurde.
refresh_tokenWird verwendet, um neue Tokens ohne erneute Authentifizierung zu erhalten. Nur vorhanden, wenn der offline_access Scope angefordert wurde.
token_typeImmer Bearer.
expires_inLebensdauer des Tokens in Sekunden.
scopeDie vom Autorisierungsserver gewährten Berechtigungen (Scopes).

Checkpoint: Teste deinen Device Flow

Teste jetzt deine Device Flow-Integration:

  1. Starte deine App und löse den Device Flow aus, um einen device_code und user_code zu erhalten.
  2. Öffne die verification_uri in einem Browser und gib den user_code ein, oder verwende verification_uri_complete, um die manuelle Codeeingabe zu überspringen.
  3. Schließe den Anmeldeprozess im Browser ab.
  4. Überprüfe, ob deine App nach dem Polling Tokens erhält.

Benutzerinformationen abrufen

ID-Token-Ansprüche dekodieren

Das im Token-Response zurückgegebene id_token ist ein standardmäßiges JSON Web Token (JWT). Du kannst den Base64URL-codierten Payload-Teil (der zweite Teil des JWT, durch . getrennt) dekodieren, um grundlegende Benutzeransprüche ohne zusätzliche Netzwerkabfrage zu erhalten.

Der dekodierte Payload enthält Ansprüche wie sub (Benutzer-ID), name, email usw., abhängig von den angeforderten Berechtigungen (Scopes).

tipp:

Für den produktiven Einsatz solltest du die JWT-Signatur validieren, bevor du den Ansprüchen vertraust. Verwende das JWKS von deinem Logto-Endpunkt (https://your.logto.endpoint/oidc/jwks), um das Token zu überprüfen.

Vom userinfo-Endpunkt abrufen

Das ID-Token enthält grundlegende Ansprüche basierend auf den angeforderten Berechtigungen (Scopes). Einige erweiterte Ansprüche (wie custom_data, identities) sind nur über den OIDC UserInfo Endpoint verfügbar:

curl --request GET 'https://your.logto.endpoint/oidc/me' \
--header 'Authorization: Bearer ACCESS_TOKEN'

Ersetze ACCESS_TOKEN durch das opake Zugangstoken (nicht das JWT-Ressourcen-Token) aus der Token-Antwort. Die Antwort ist ein JSON-Objekt mit den Benutzeransprüchen basierend auf den gewährten Berechtigungen.

Zusätzliche Ansprüche anfordern

Du stellst möglicherweise fest, dass einige Benutzerinformationen im ID-Token fehlen. Das liegt daran, dass OAuth 2.0 und OpenID Connect (OIDC) nach dem Prinzip der minimalen Rechtevergabe (PoLP) konzipiert sind und Logto auf diesen Standards aufbaut.

Standardmäßig werden begrenzte Ansprüche zurückgegeben. Wenn du mehr Informationen benötigst, kannst du zusätzliche Berechtigungen anfordern, um auf mehr Ansprüche zuzugreifen.

info:

Ein "Anspruch (Claim)" ist eine Behauptung über ein Subjekt; eine "Berechtigung (Scope)" ist eine Gruppe von Ansprüchen. Im aktuellen Fall ist ein Anspruch ein Informationsstück über den Benutzer.

Hier ist ein nicht-normatives Beispiel für die Beziehung zwischen Berechtigung und Anspruch:

tipp:

Der "sub"-Anspruch bedeutet "Subjekt", was der eindeutige Identifikator des Benutzers ist (d. h. Benutzer-ID).

Das Logto SDK wird immer drei Berechtigungen anfordern: openid, profile und offline_access.

Um zusätzliche Berechtigungen (Scopes) anzufordern, füge sie in den scope-Parameter der Device Authorization Anfrage ein. Um beispielsweise die E-Mail und Telefonnummer des Benutzers anzufordern:

curl --request POST 'https://your.logto.endpoint/oidc/device/auth' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=your-application-id' \
--data-urlencode 'scope=openid offline_access profile email phone'

Berechtigungen und Ansprüche

Hier ist die Liste der unterstützten Berechtigungen (Scopes) und der entsprechenden Ansprüche (Claims):

Standard OIDC-Berechtigungen (Scopes)

openid (Standard)

Claim-NameTypBeschreibung
substringDer eindeutige Identifikator des Benutzers

profile (Standard)

Claim-NameTypBeschreibung
namestringDer vollständige Name des Benutzers
usernamestringDer Benutzername des Benutzers
picturestringURL zum Profilbild des Endbenutzers. Diese URL MUSS auf eine Bilddatei (z. B. PNG, JPEG oder GIF) verweisen, nicht auf eine Webseite mit einem Bild. Beachte, dass diese URL speziell auf ein Profilfoto des Endbenutzers verweisen SOLLTE, das zur Darstellung des Endbenutzers geeignet ist, und nicht auf ein beliebiges vom Endbenutzer aufgenommenes Foto.
created_atnumberZeitpunkt, zu dem der Endbenutzer erstellt wurde. Die Zeit wird als Anzahl der Millisekunden seit der Unix-Epoche (1970-01-01T00:00:00Z) dargestellt.
updated_atnumberZeitpunkt, zu dem die Informationen des Endbenutzers zuletzt aktualisiert wurden. Die Zeit wird als Anzahl der Millisekunden seit der Unix-Epoche (1970-01-01T00:00:00Z) dargestellt.

Weitere Standard-Ansprüche (Claims) wie family_name, given_name, middle_name, nickname, preferred_username, profile, website, gender, birthdate, zoneinfo und locale werden ebenfalls im profile-Scope enthalten sein, ohne dass der userinfo-Endpunkt angefragt werden muss. Ein Unterschied zu den oben genannten Claims besteht darin, dass diese Claims nur zurückgegeben werden, wenn ihre Werte nicht leer sind, während die oben genannten Claims null zurückgeben, wenn die Werte leer sind.

hinweis:

Im Gegensatz zu den Standard-Claims verwenden die Claims created_at und updated_at Millisekunden anstelle von Sekunden.

email

Claim-NameTypBeschreibung
emailstringDie E-Mail-Adresse des Benutzers
email_verifiedbooleanOb die E-Mail-Adresse verifiziert wurde

phone

Claim-NameTypBeschreibung
phone_numberstringDie Telefonnummer des Benutzers
phone_number_verifiedbooleanOb die Telefonnummer verifiziert wurde

address

Bitte siehe die OpenID Connect Core 1.0 für Details zum Address-Claim.

info:

Scopes, die mit (Standard) gekennzeichnet sind, werden immer vom Logto SDK angefordert. Claims unter den Standard-OIDC-Scopes sind immer im ID-Token enthalten, wenn der entsprechende Scope angefordert wird — sie können nicht deaktiviert werden.

Erweiterte Berechtigungen (Scopes)

Die folgenden Scopes sind von Logto erweitert und liefern Claims über den userinfo-Endpunkt. Diese Claims können auch so konfiguriert werden, dass sie direkt im ID-Token enthalten sind, über Konsole > Benutzerdefiniertes JWT. Siehe Benutzerdefiniertes ID-Token für weitere Details.

custom_data

Claim-NameTypBeschreibungStandardmäßig im ID-Token enthalten
custom_dataobjectDie benutzerdefinierten Daten des Benutzers

identities

Claim-NameTypBeschreibungStandardmäßig im ID-Token enthalten
identitiesobjectDie verknüpften Identitäten des Benutzers
sso_identitiesarrayDie verknüpften SSO-Identitäten des Benutzers

roles

Claim-NameTypBeschreibungStandardmäßig im ID-Token enthalten
rolesstring[]Die Rollen (Roles) des Benutzers

urn:logto:scope:organizations

Claim-NameTypBeschreibungStandardmäßig im ID-Token enthalten
organizationsstring[]Die Organisations-IDs, denen der Benutzer angehört
organization_dataobject[]Die Organisationsdaten, denen der Benutzer angehört
hinweis:

Diese Organisations-Claims können auch über den userinfo-Endpunkt abgerufen werden, wenn ein opaker Token verwendet wird. Allerdings können opake Tokens nicht als Organisationstoken für den Zugriff auf organisationsspezifische Ressourcen verwendet werden. Siehe Opaker Token und Organisationen für weitere Details.

urn:logto:scope:organization_roles

Claim-NameTypBeschreibungStandardmäßig im ID-Token enthalten
organization_rolesstring[]Die Organisationsrollen, denen der Benutzer angehört, im Format <organization_id>:<role_name>

API-Ressourcen und Organisationen

Wir empfehlen, zuerst 🔐 Rollenbasierte Zugangskontrolle (RBAC) zu lesen, um die grundlegenden Konzepte von Logto RBAC zu verstehen und wie man API-Ressourcen richtig einrichtet.

Zugriff auf API-Ressourcen anfordern

Um auf eine bestimmte API-Ressource zuzugreifen, füge den resource-Parameter in die Device Authorization Anfrage ein:

curl --request POST 'https://your.logto.endpoint/oidc/device/auth' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=your-application-id' \
--data-urlencode 'scope=openid offline_access' \
--data-urlencode 'resource=https://your-api-resource-indicator'

Sobald der Benutzer die Autorisierung abgeschlossen hat und du ein Auffrischungstoken (refresh_token) erhalten hast, kannst du JWT-Zugangstokens für die API-Ressource abrufen:

curl --request POST 'https://your.logto.endpoint/oidc/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=your-application-id' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'refresh_token=REFRESH_TOKEN' \
--data-urlencode 'resource=https://your-api-resource-indicator'

Die Antwort enthält ein JWT access_token mit aud auf deinen API-Ressourcenindikator gesetzt.

hinweis:

Das refresh_token ist nur verfügbar, wenn der offline_access Scope in der initialen Device Authorization Anfrage enthalten ist. Speichere und verwende immer das neueste refresh_token, da Logto Token-Rotation verwendet.

Organisationstokens abrufen

Falls Organisationen neu für dich sind, lies bitte 🏢 Organisationen (Multi-Tenancy), um loszulegen.

Um organisationsbezogene Informationen anzufordern, füge den Scope urn:logto:scope:organizations in die Device Authorization Anfrage ein:

curl --request POST 'https://your.logto.endpoint/oidc/device/auth' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=your-application-id' \
--data-urlencode 'scope=openid offline_access urn:logto:scope:organizations' \
--data-urlencode 'resource=urn:logto:resource:organizations'

Sobald der Benutzer angemeldet ist, kannst du Organisationstokens mit dem Auffrischungstoken abrufen:

curl --request POST 'https://your.logto.endpoint/oidc/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=your-application-id' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'refresh_token=REFRESH_TOKEN' \
--data-urlencode 'organization_id=your-organization-id'

Die Antwort enthält ein Zugangstoken, das auf die angegebene Organisation beschränkt ist.

Organisations-API-Ressourcen

Um ein Zugangstoken für eine API-Ressource innerhalb einer Organisation zu erhalten, füge sowohl die Parameter resource als auch organization_id hinzu:

curl --request POST 'https://your.logto.endpoint/oidc/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=your-application-id' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'refresh_token=REFRESH_TOKEN' \
--data-urlencode 'organization_id=your-organization-id' \
--data-urlencode 'resource=https://your-api-resource-indicator'

Weiterführende Literatur

Endbenutzerflüsse: Authentifizierungsflüsse, Kontoflüsse und Organisationsflüsse Connectors konfigurieren Autorisierung (Authorization)