OAuth und OpenID Connect sind zwei grundlegende Technologien, die moderne Entwickler ständig nutzen, die sie jedoch häufig unpräzise beschreiben. Leute sagen beiläufig Dinge wie "OAuth-Login" oder "Sicher anmelden mit OAuth". Manchmal ist diese lockere Formulierung nur harmloser Branchen-Jargon, aber in anderen Fällen verdeckt sie einen unglaublich wichtigen architektonischen Unterschied. OAuth 2.0 ist im Grunde ein Framework, das vollständig um Autorisierung herum aufgebaut ist. OpenID Connect, fast immer zu OIDC abgekürzt, ist eine Identitätsschicht, die strikt für die Authentifizierung entwickelt wurde.
Dieser semantische Unterschied klingt rein akademisch, bis man tatsächlich eine echte, produktionsreife Anwendung baut. Wenn man mit dem falschen mentalen Modell arbeitet, kann es leicht passieren, dass man ein standardmäßiges Access Token als definitiven Beweis für die Benutzeridentität behandelt, wichtige Token-Verifizierungsschritte gefährlich überspringt, hochsensible Token unsicher auf mobilen Geräten speichert oder törichterweise davon ausgeht, dass sich jeder einzelne Identity Provider genau wie Google verhält.
Die absolut einfachste Version dieser Unterscheidung ist diese: OAuth beantwortet entschlossen die entscheidende Frage: "Was genau darf diese spezifische Anwendung tun?" OIDC hingegen beantwortet klar die völlig andere Frage: "Wer genau ist dieser spezifische Benutzer?" OIDC baut buchstäblich direkt auf dem etablierten OAuth 2.0-Framework auf und fügt dem bestehenden Autorisierungsablauf von OAuth nahtlos eine robuste, hochgradig standardisierte Identitätsschicht hinzu.
Die Analogie von Armband und Ausweis
Stellen Sie sich vor, Sie versuchen, in einen exklusiven Nachtclub zu gelangen.
OAuth ist im Grunde genau so, als würde man an der Tür ein buntes Armband erhalten. Es zeigt dem Türsteher und dem Personal des Veranstaltungsortes deutlich, zu welchen Bereichen Sie offiziell Zugang haben. Vielleicht bedeutet Ihr Armband, dass Sie den abgesperrten VIP-Bereich betreten dürfen, oder vielleicht signalisiert es, dass Sie direkt an der Premium-Bar bestellen dürfen. In jeder Hinsicht repräsentiert das Armband ausschließlich eine erteilte Erlaubnis. Aber entscheidend ist: Das Armband beweist absolut nicht, wer Sie tatsächlich sind. Es zeigt nicht Ihren gesetzlichen Namen, es fehlt Ihr Foto, es bestätigt nicht Ihr Alter und es enthält keine offizielle Identitätsnummer.
OIDC ist genau so, als würde man genau dasselbe Armband erhalten und gleichzeitig gezwungen werden, einen sehr vertrauenswürdigen staatlichen Ausweis mit sich zu führen. Sie behalten immer noch alle Ihre gewährten Berechtigungen durch das Armband, aber Sie besitzen nun auch ein weithin vertrauenswürdiges, standardisiertes Identitätsdokument, das definitiv feststellt, wer Sie tatsächlich sind.
Dieses Szenario ist genau das, was technisch in der Softwarewelt passiert:
OAuth 2.0 gives you:
Access token
Used to call APIs
OIDC gives you:
Access token
Used to call APIs
ID token
Used to identify the userDas Access Token und das ID Token sind funktionale Geschwister. Ein Token ist absolut kein Ersatz oder Austausch für das andere.
Was OAuth 2.0 tatsächlich tut
In seinem absoluten Kern ermöglicht OAuth 2.0 einem Benutzer lediglich, einer Drittanbieteranwendung sicher die ausdrückliche Erlaubnis zu erteilen, in seinem Namen auf eine stark geschützte Ressource zuzugreifen. Ein sehr häufiges Beispiel aus der Praxis ist die Verbindung einer neuen App mit Ihrem bestehenden GitHub-Konto. Die Anwendung leitet den Benutzer nahtlos direkt zu GitHub weiter und fragt explizit nach gezieltem Repository-Zugriff.
https://github.com/login/oauth/authorize?
client_id=abc123&
scope=repo&
redirect_uri=https://myapp.com/callbackGitHub präsentiert dem Benutzer anschließend einen klaren Zustimmungsbildschirm. Wenn der Benutzer die Anfrage positiv bestätigt, leitet GitHub ihn sicher an die ursprüngliche App zurück und übermittelt dabei einen temporären Autorisierungscode.
https://myapp.com/callback?code=xyz789Hinter den Kulissen tauscht die Anwendung dann diesen temporären Code sicher gegen ein viel langlebigeres Access Token aus.
POST https://github.com/login/oauth/access_token
Content-Type: application/x-www-form-urlencoded
client_id=abc123&
client_secret=secret456&
code=xyz789&
redirect_uri=https://myapp.com/callbackDie Antwort des Providers enthält wichtigerweise das neu erstellte Access Token.
{
"access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a",
"token_type": "bearer",
"scope": "repo"
}Genau dieses Token kann nun wiederholt verwendet werden, um im Namen des Benutzers stark geschützte GitHub-APIs aufzurufen.
GET https://api.github.com/user/repos
Authorization: Bearer gho_16C7e42F292c6912E7710c838347Ae178B4aBeachten Sie genau, was OAuth uns während dieses gesamten Prozesses im Grunde nicht gegeben hat. Es hat uns absolut keine Art von Standard-Identitäts-Token gegeben. Es gab uns strikt eine stark eingeschränkte Erlaubnis, eine API aufzurufen. Speziell bei GitHub sind Sie, wenn Sie tatsächlich die Identität des Benutzers feststellen wollen, gezwungen, dieses Access Token zu verwenden, um manuell eine explizite Identitäts-API aufzurufen, wie z. B. GET /user. Dieser zusätzliche Schritt existiert genau deshalb, weil GitHubs häufigster Login-Ablauf reines OAuth 2.0 anstelle von OIDC verwendet.
Was OIDC hinzufügt
OIDC beginnt intelligenterweise mit genau demselben grundlegenden OAuth-Ablauf, fügt jedoch explizit einen dringend erforderlichen, standardisierten Identitäts-Scope namens openid hinzu. Ein typischer Google-Anmeldeaufruf enthält beispielsweise fast immer eine Gruppe von Scopes, die genau so aussieht:
scope=openid profile emailDieser einfache openid-Scope fungiert als definitives Signal an den Provider, dass dies formell ein OpenID Connect-Ablauf ist. Die anfragende App gibt ausdrücklich an, dass sie nicht nur nach einem Standard-API-Zugriff fragt; sie bittet den zugrunde liegenden Provider aktiv darum, den Benutzer rigoros zu authentifizieren und dann seine Identitätsinformationen in einem hochgradig standardisierten, weltweit anerkannten Format zurückzugeben.
Nach Abschluss des standardmäßigen Code-Austauschs gibt ein OIDC-konformer Provider vorhersehbar sowohl ein Access Token als auch ein ID Token gleichzeitig zurück.
{
"access_token": "ya29.a0AfH6SMBxC...",
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE2...",
"refresh_token": "1//04dGKC8...",
"expires_in": 3600,
"token_type": "Bearer"
}Das Access Token bleibt fest und exklusiv für den Aufruf von APIs bestimmt. Das neu eingeführte ID Token fungiert als das hochgradig vertrauenswürdige Identitätsdokument. Entscheidend ist, dass das ID Token fast immer als JWT (JSON Web Token) formatiert ist, was strikt vorschreibt, dass es aus drei verschiedenen Teilen besteht: einem Header, einem Payload und einer kryptografischen Signatur.
header.payload.signatureDer zentrale Payload enthält umfangreiche Claims bezüglich des spezifischen Benutzers und der genauen Umstände des Authentifizierungsereignisses selbst.
{
"sub": "109651783456723954281",
"name": "John Doe",
"email": "john.doe@gmail.com",
"email_verified": true,
"picture": "https://lh3.googleusercontent.com/a-/abc123",
"iss": "https://accounts.google.com",
"aud": "1234567890-abcd1234.apps.googleusercontent.com",
"iat": 1712345678,
"exp": 1712349278
}Der sub-Claim dient durchgängig als hochstabile, serverseitige eindeutige Benutzer-ID. Der iss-Claim informiert Sie zuverlässig darüber, wer genau das Token sicher ausgestellt hat. Der aud-Claim gibt definitiv an, für welche spezifische Client-Anwendung das Token absichtlich ausgestellt wurde. Der exp-Claim definiert klar, wann das Token mathematisch abläuft. Diese eingebetteten Claims sind jedoch völlig nutzlos und potenziell gefährlich, es sei denn, Sie überprüfen zuerst aktiv und korrekt die kryptografische Integrität des Tokens.
Niemals ein ID Token einfach nur decodieren
Ein unglaublich häufiger, extrem gefährlicher Anfängerfehler ist es, das JWT faul aufzuteilen, den Base64-Payload zu decodieren und blind jedem Text zu vertrauen, den es zufällig enthält. Dieser leichtsinnige Prozess ist absolut keine Verifizierung; es ist lediglich Text-Parsing.
Ein JWT ist nur deshalb wirklich nützlich, weil es vom Aussteller kryptografisch signiert wird. Ihr sicheres Backend muss diese eingebettete Signatur rigoros gegen die öffentlich gehosteten Schlüssel des Identity Providers überprüfen. Darüber hinaus muss es den Aussteller streng validieren, das Publikum strikt überprüfen, die Ablaufzeit durchsetzen und alle anderen spezifischen Claims, von denen Ihre Anwendung entscheidend abhängt, aggressiv validieren.
Die standardmäßige Backend-Verifizierungs-Checkliste ist in ihrem Kernkonzept bemerkenswert einfach:
| Prüfung | Warum es wichtig ist |
|---|---|
| Signatur | Beweist, dass das Token tatsächlich vom vertrauenswürdigen Provider stammt |
| Aussteller | Verhindert, dass gefälschte Token vom falschen Provider vollständig akzeptiert werden |
| Publikum | Verhindert, dass versehentlich gültige Token akzeptiert werden, die für eine andere App bestimmt sind |
| Ablauf | Verhindert strikt die bösartige Wiederverwendung alter, abgelaufener Token |
| E-Mail-Verifizierung | Verhindert effektiv das blinde Vertrauen in unbestätigte, potenziell gefälschte E-Mail-Adressen |
Eine stark vereinfachte Version einer sicheren Backend-Verifizierungsfunktion sieht normalerweise in etwa so aus:
def verify_token(token):
public_key = fetch_provider_public_key(token)
payload = jwt.decode(
token,
public_key,
algorithms=["RS256"],
audience=YOUR_CLIENT_ID,
issuer="https://accounts.google.com",
)
if not payload.get("email_verified"):
raise ValueError("Email is not verified")
return payloadIn einer echten Produktionsumgebung benötigen Sie unweigerlich auch robuste JWKS-Caching-Mechanismen, ausgeklügelte Logik für die Schlüsselrotation und stark anbieterspezifische Validierungsregeln. Die wichtigste übergreifende Idee ist, dass eine robuste Identitätsprüfung grundlegend sicher ins Backend gehört und absolut nicht nur in vom Frontend decodierte, leicht manipulierbare Token-Payloads.
Provider-Unterschiede sind wichtig
Es ist wichtig zu verstehen, dass nicht jeder einzelne "Mit X anmelden"-Button tatsächlich OIDC unter der Haube verwendet. Massive Provider wie Google, Apple, Microsoft, Auth0, Keycloak und Zitadel sowie zahlreiche moderne Identitätsplattformen unterstützen den OIDC-Standard vollständig. In diesen hochmodernen Abläufen können Sie zuverlässig erwarten, ein standardmäßiges, überprüfbares ID Token zu erhalten.
Der am häufigsten verwendete OAuth-Anwendungsablauf von GitHub ist jedoch deutlich anders. Er stellt typischerweise nur ein Access Token bereit. Um tatsächlich die Profilinformationen des Benutzers zu erhalten, sind Sie gezwungen, dieses Token zu verwenden, um die GitHub-API manuell aufzurufen.
const userResponse = await fetch("https://api.github.com/user", {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const user = await userResponse.json();Dieser Ansatz ist nicht zwangsläufig inhärent schlechter, aber er ist unbestreitbar anders. Reines OAuth kann in modernen Anmeldeabläufen absolut noch erfolgreich eingesetzt werden, aber der eigentliche Identitätsabrufmechanismus wird vollständig anbieterspezifisch, es sei denn, der gewählte Anbieter unterstützt explizit den OIDC-Standard. Diese nuancierte Unterscheidung wirkt sich auch stark auf Kontoverknüpfungsstrategien aus. Mit echtem OIDC fungiert der sub-Claim durchgängig als hochstabile Identitätstaste für diesen bestimmten Anbieter. Bei reinen OAuth-Anbietern müssen Sie jedoch die eindeutige Benutzer-ID des Anbieters, die direkt aus seiner benutzerdefinierten API-Antwort abgeleitet wird, manuell abrufen und sorgfältig speichern.
Managed Auth vs Self-Hosted OIDC
In der realen Welt der Anwendungsentwicklung stehen Sie fast immer vor der Wahl zwischen der Nutzung eines vollständig verwalteten Authentifizierungsanbieters und der mühsamen Implementierung einer robusten OIDC-Integration komplett durch Sie selbst.
Verwaltete Dienste wie Clerk, Auth0 und Firebase Auth existieren speziell, um die überwiegende Mehrheit der qualvollen Protokolldetails zu abstrahieren und zu verbergen. Sie kümmern sich mühelos um dichte Provider-Konfigurationen, komplexe Token-Austausche, aggressives Token-Refreshing, sichere Sitzungsverwaltung, persistente Benutzerdatensätze und tief integrierte SDKs. Dieser "Batteries-included"-Ansatz ist unglaublich attraktiv, wenn die reine Entwicklungsgeschwindigkeit wirklich zählt.
Umgekehrt bieten selbst gehostete Identity Provider wie Zitadel oder Keycloak eine deutlich granularere Kontrolle. Sie sind häufig die weitaus bessere Wahl für strenge Datenhoheitsanforderungen, intensive Einhaltung gesetzlicher Vorschriften, tiefe Workflow-Anpassungen oder massive Kosteneinsparungen im Unternehmensmaßstab. Der Kompromiss besteht jedoch darin, dass Sie in hohem Maße für einen viel größeren Teil des Integrationsaufwands verantwortlich sind.
Bei einem verwalteten Provider verlässt sich Ihr Backend möglicherweise einfach auf die Verifizierung eines leichtgewichtigen Sitzungstokens, das explizit vom benutzerdefinierten SDK dieses Providers generiert wurde.
async def require_auth(request):
request_state = clerk.authenticate_request(
request={"headers": dict(request.headers), "url": str(request.url)}
)
if not request_state.is_signed_in:
raise HTTPException(status_code=401)
return request_state.payloadMit einem selbst gehosteten OIDC-Anbieter sind Sie in der Regel vollständig dafür verantwortlich, den Autorisierungsendpunkt, den Token-Endpunkt, die Client-ID, die Redirect-URI, die angeforderten Scopes und die intensive Backend-JWT-Verifizierungslogik komplett von Grund auf manuell zu konfigurieren. Keiner dieser spezifischen Ansätze ist universell richtig oder falsch. Verwaltete Authentifizierung reduziert den operativen Aufwand drastisch, während selbst gehostete Lösungen die langfristige Kontrolle dramatisch erhöhen.
Mobile Apps benötigen PKCE
Es ist absolut entscheidend zu erkennen, dass mobile Anwendungen im Grunde nicht genau dasselbe sind wie traditionelle, servergerenderte Webanwendungen. Eine traditionelle Webanwendung kann ein hochsensibles Client-Secret sicher und dauerhaft ausschließlich auf dem Backend-Server speichern. Eine native mobile App kann das absolut nicht. Buchstäblich alles, was kompiliert und in einer öffentlichen APK- oder IPA-Datei ausgeliefert wird, kann von einem halbwegs entschlossenen Benutzer oder einem automatisierten Skript trivial extrahiert werden. Diese harte Realität bedeutet, dass native mobile Apps unweigerlich als hochgradig gefährdete "öffentliche Clients" behandelt werden müssen.
Genau diese eklatante Schwachstelle ist der Grund, warum alle mobilen OAuth- und OIDC-Abläufe rigoros PKCE nutzen sollten, was für Proof Key for Code Exchange steht. PKCE fügt dem Ablauf auf clevere Weise ein temporäres, hochdynamisches Geheimnis pro Anmeldung hinzu. Die mobile App generiert lokal einen zufälligen code_verifier, hasht ihn sicher zu einer code_challenge, die während der anfänglichen Autorisierungsanfrage gesendet wird, und beweist später schlüssig, dass sie den ursprünglichen Verifier kennt, wenn der Code schließlich gegen echte Tokens eingetauscht wird.
1. App creates a random code_verifier
2. App hashes it into a code_challenge
3. Authorization request includes the code_challenge
4. Provider returns an authorization code
5. Token request includes the original code_verifier
6. Provider checks that it matches the challengeIm beliebten Expo-Ökosystem wird dieser komplexe Tanz fast immer sauber direkt durch die Bibliothek expo-auth-session abgewickelt.
const [request, response, promptAsync] = AuthSession.useAuthRequest(
{
clientId: CLIENT_ID,
scopes: ["openid", "profile", "email"],
redirectUri,
usePKCE: true,
},
discovery
);Darüber hinaus benötigen mobile Apps dringend eine unglaublich sichere lokale Token-Speicherung. Sie dürfen hochsensible Token niemals in einen unverschlüsselten, leicht lesbaren Async-Speicher ablegen. In einer Expo-Umgebung sollten Sie immer strikt expo-secure-store verwenden, um jedes sensible Token-Material abzusichern.
import * as SecureStore from "expo-secure-store";
await SecureStore.setItemAsync("id_token", idToken);
const savedToken = await SecureStore.getItemAsync("id_token");Die drei Token-Schichten
Eine massive, beständige Quelle immenser Verwirrung ist die einfache Tatsache, dass moderne Anwendungen fast immer mit weitaus mehr als nur einer Art von Token gleichzeitig jonglieren. Der externe Identity Provider kann problemlos sowohl ein ID Token als auch ein separates Access Token ausgeben. Als Reaktion darauf kann Ihr internes Backend dann dynamisch sein ganz eigenes, proprietäres Sitzungstoken erstellen. Um die Sache noch komplizierter zu machen, könnte der Provider auch gleichzeitig ein langlebiges Refresh Token ausgeben.
Diese stark variierenden Token erfüllen innerhalb der Architektur völlig unterschiedliche, hochspezialisierte Zwecke.
| Token | Aussteller | Zweck |
|---|---|---|
| ID Token | Identity Provider | Beweist definitiv, wer genau der Benutzer ist |
| Access Token | Identity- oder API-Provider | Autorisiert strikt nachgelagerte API-Aufrufe |
| App-Sitzungstoken | Ihre App oder Auth-Plattform | Authentifiziert laufende Anfragen direkt an Ihr Backend |
| Refresh Token | Provider | Beschafft sicher neue, kurzlebige Token, wenn alte ablaufen |
Ein sehr häufiger, hochgradig robuster architektonischer Ablauf sieht normalerweise in etwa so aus:
Google ID token -> Your backend verifies it -> Your backend creates an app sessionNach diesem anfänglichen Austausch kann Ihre Client-App einfach Ihr eigenes stark angepasstes Sitzungstoken verwenden, um Ihre interne API effizient aufzurufen. Es ist absolut nicht erforderlich, das riesige Google ID Token bei jeder einzelnen Netzwerkanfrage kontinuierlich zu übertragen, es sei denn, Ihre spezielle Architektur wurde absichtlich genau so konzipiert.
Häufige Missverständnisse
Der absolut häufigste, allgegenwärtige Fehler in der Branche besteht darin, beiläufig zu behaupten, dass OAuth buchstäblich "Login" bedeutet. OAuth kann sicherlich stark genutzt werden, um sicher an einem breiteren Login-Ablauf teilzunehmen, aber bei OAuth selbst geht es strikt und vollständig um delegierte Autorisierung. OIDC ist die tatsächliche, stark standardisierte Identitätsschicht, die speziell dafür entwickelt wurde, Personen anzumelden.
Ein weiterer massiver, häufig anzutreffender Fehler ist der Versuch, das ID Token direkt zur Autorisierung von API-Aufrufen zu verwenden. Das ID Token existiert ausschließlich für den Frontend-Client oder den Backend-Server, um die Identität des Benutzers definitiv zu verstehen. Das Access Token existiert ausschließlich für eine robuste API-Autorisierung. Das Verwischen dieser beiden Grenzen führt ständig zu schwerwiegenden architektonischen Fehlern.
Das Logout-Verhalten stellt einen weiteren unglaublich subtilen Bereich der Verwirrung dar. Das Abmelden eines Benutzers von Ihrer speziellen Anwendung löscht normalerweise nur Ihre lokale App-Sitzung und entfernt lokale Token rigoros. Es zwingt den Benutzer absolut nicht zwangsläufig, sich bei Google, Apple oder jeder einzelnen anderen verbundenen App abzumelden, die sich auf seinem physischen Gerät befindet. Diese strikte Trennung des Sitzungsstatus ist völlig normal und wird erwartet.
Schließlich sollten die angeforderten Berechtigungsbereiche (Scopes) immer so minimal wie menschenmöglich gehalten werden. Wenn Ihre App wirklich nur die Identität des Benutzers kennen muss, sollten Sie immer nur die Scopes openid profile email anfordern. Sie sollten absolut niemals beiläufig nach weitreichendem Zugriff auf seinen Kalender, sein privates Laufwerk, persönliche Fotos oder anderen weitreichenden Berechtigungen fragen, es sei denn, Ihre Anwendung benötigt sie tatsächlich grundlegend, um zu funktionieren.
Die praktische Zusammenfassung
OAuth 2.0 ist im Grunde das Berechtigungs-Framework. Es ermöglicht einer bestimmten Anwendung definitiv, etwas unglaublich Spezifisches im Namen eines Benutzers zu tun. OIDC ist die standardisierte Identitätsschicht, die direkt darauf aufbaut. Es ermöglicht einer Anwendung auf universell standardisierte Weise sicher und zuverlässig zu wissen, wer der Benutzer tatsächlich ist.
Verwenden Sie das Access Token ausschließlich zum Aufrufen von APIs. Verwenden Sie das ID Token ausschließlich zur Überprüfung der Identität. Überprüfen Sie Token immer rigoros direkt im Backend. Setzen Sie PKCE für native mobile Anwendungen immer aggressiv durch. Speichern Sie sensible Token immer in hochsicheren, verschlüsselten Speichern. Behandeln Sie Unterschiede zwischen Identity Providern immer als höchst reale architektonische Einschränkungen und nicht nur als kosmetische Variationen.
Wenn Sie sich aus diesem Artikel absolut nichts anderes merken, zwingen Sie sich, diese eine eiserne Regel zu behalten: OAuth gibt Ihrer App lediglich eine Erlaubnis, aber OIDC gibt Ihrer App definitiv eine Identität.
Referenzen
Mehr lesen
API-Schlüssel-Pooling mit Bifrost
Ein praktischer Leitfaden zur Konfiguration von API-Key-Pooling in Bifrost und zur sicheren Skalierung über mehrere Knoten durch Externalisierung der Rate Limits.
Architektur für zuverlässige mobile Abrechnung: Was ich auf die harte Tour gelernt habe
Ein Praxisblick auf die Reparatur von mobiler Abonnement-Abrechnung, wenn Webhooks, Sandbox-Käufe und Benutzeridentität versagen.
Wie Mobile Apps funktionieren
Die drei Wege, eine Mobile-App zu bauen, was bei jedem unter der Haube tatsächlich läuft, und das gemeinsame Architektur-Muster hinter React Native, Flutter und Tauri Mobile.
