OAuth 2.0 Flows Authorization Code, PKCE, and Client Credentials
Ein Leitfaden für Entwickler, um den richtigen OAuth 2.0-Fluss auszuwählen. Beinhaltet die Autorisierung durch Code (Webanwendungen), PKCE (Single-Page-Anwendungen und Mobilgeräte) und Clientanmeldedaten (Server-zu-Server) mit funktionierenden Codebeispielen und den Fehlern, die Sie später erleben.
Drei Flows decken 95% echter OAuth 2.0-Anwendungsfälle ab. Die Spezifikation definiert mehr, aber der Rest ist veraltet, ein Randfall oder beides. Wählen Sie von Anfang an den richtigen, dann vermeiden Sie eine schmerzhafte Umstrukturierung, wenn die Authentifizierungsaufgaben sich ändern.
| Flow | Wann wird es verwendet | Benutzer beteiligt? | Bedarf an client_secret? |
|---|---|---|---|
| Authorization Code | Webanwendung mit einem Backend-Server | Ja | Ja – bleibt auf dem Server |
| Authorization Code + PKCE | SPA, Mobilanwendung, jeder öffentliche Client | Ja | NEIN |
| Client Credentials | Server-zu-Server (kein Benutzer) | NEIN | Ja – bleibt auf dem Server |
Authorization Code Flow
Der Standardflow für Webanwendungen mit Backend. Der Zugriffstoken und der client_secret berühren niemals den Browser – der Tokenaustausch erfolgt serverseitig. Das ist der gesamte Punkt.
Schritt 1: Leiten Sie den Benutzer um
Bauen Sie eine Autorisierungs-URL und leiten Sie den Browser darauf um:
GET https://accounts.example.com/oauth/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&scope=openid+profile+email
&state=RANDOM_CSRF_TOKEN
Der state Der Wert dient als CSRF-Versicherung für die Umleitung. Erstellen Sie einen neuen zufälligen String pro Flow, speichern Sie ihn in der Sitzung und überprüfen Sie ihn, wenn der Benutzer zurückkommt. Wenn Sie diese Prüfung überspringen, kann ein Angreifer Benutzer durch einen eigenen Autorisierungscode führen – ohne dass der Benutzer es merkt, und verknüpft so die Konten des Benutzers mit der Identität des Angreifers.
Schritt 2: Behandeln Sie die Rückruf-URL
Der Autorisierungs-Server leitet Sie zurück an Ihre redirect_uri mit einem kurzlebigen Code:
GET https://yourapp.com/callback?code=AUTH_CODE&state=SAME_STATE_YOU_SENT
Überprüfen state stimmt mit dem, was Sie gespeichert haben. Austauschen Sie dann den Code serverseitig.
Schritt 3: Austauschen des Codes gegen Tokens (nur serverseitig)
POST https://accounts.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE
&redirect_uri=https://yourapp.com/callback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Die Antwort:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "def50200a12b3c...",
"scope": "openid profile email"
}
Halten Sie beide Tokens serverseitig. Wenn access_token abläuft (überprüfen Sie expires_in), verwenden Sie das refresh_token um ein neues Token zu erhalten, ohne den Benutzer erneut durch die Anmeldung zu führen.
PKCE – Für Clients, die keine Geheimnisse speichern können
Eine SPA oder Mobilanwendung hat keinen sicheren Ort für ein client_secret. Jeder kann DevTools öffnen und es in Ihrem JS-Bundle finden. Jeder kann Ihre APK dekompilieren. PKCE (Proof Key for Code Exchange, ausgesprochen „pixy“) löst dies mit einem einmaligen kryptografischen Challenge – kein gemeinsames Geheimnis erforderlich.
Der Flow ist identisch mit dem Authorization Code mit zwei Zusätzen: einem code_verifier (zufälligen String, den Sie generieren) und einem code_challenge (SHA-256-Hash des Verifizierers, base64url-gekennzeichnet). Sie senden die Challenge vorab und beweisen dann bei der Austauschzeit, dass Sie den Verifizierer besitzen.
Schritt 1: Generieren Sie den Verifizierer und die Challenge
function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return base64url(array);
}
async function generateCodeChallenge(verifier) {
const data = new TextEncoder().encode(verifier);
const digest = await crypto.subtle.digest('SHA-256', data);
return base64url(new Uint8Array(digest));
}
function base64url(buffer) {
return btoa(String.fromCharCode(...buffer))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// Usage
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
// Store codeVerifier in memory — NOT localStorage
Speichern Sie den code_verifier in der Speicherung – eine modulare Variable, nicht localStorage. Sie senden ihn bei der Tokenaustauschzeit.
Schritt 2: Autorisierungsanfrage – fügen Sie die Challenge hinzu
GET https://accounts.example.com/oauth/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&scope=openid+profile
&state=RANDOM_CSRF_TOKEN
&code_challenge=BASE64URL_SHA256_OF_VERIFIER
&code_challenge_method=S256
Schritt 3: Tokenaustausch – Verifizierer statt client_secret
POST https://accounts.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE
&redirect_uri=https://yourapp.com/callback
&client_id=YOUR_CLIENT_ID
&code_verifier=ORIGINAL_VERIFIER_YOU_GENERATED
Der Autorisierungs-Server hashet den Verifizierer und vergleicht ihn mit der Challenge, die Sie im Schritt 2 gesendet haben. Ein Angreifer, der den Auth-Code abgefangen hat, hat keine Ahnung, was der Verifizierer ist – er kann ihn nicht austauschen.
Wichtig zu wissen: OAuth 2.1 (die laufende Modernisierung von 2.0) verpflichtet PKCE für alle Flows mit Umleitungen. Wenn Sie neues Code schreiben, verwenden Sie PKCE unabhängig davon, ob Ihr Anbieter es derzeit erfordert.
Client Credentials – Kein Benutzer, kein Problem
Hintergrundjobs, Microservices, die andere Microservices aufrufen, Cron-Aufgaben, die eine API aufrufen – keiner dieser Fälle beinhaltet einen Benutzer. Client Credentials ist der richtige Flow: Der Dienst authentifiziert direkt mit seinem eigenen Client-ID und Geheimnis.
POST https://accounts.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&scope=api:read api:write
Antwort:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 86400
}
Kein Refresh-Token – wenn es abläuft, beantragen Sie einfach ein neues. Der häufige Fehler: Jede API-Aufruf führt direkt zum Token-Endpoint. Speichern Sie das Token, überprüfen Sie die Ablaufzeit vor jedem Aufruf und fordern Sie nur dann eine Neuaufnahme an, wenn es kurz vor dem Ablauf steht. Ein Token-Aufruf pro Tag (oder pro Stunde, je nach expires_in) statt ein Aufruf pro Anfrage:
let cachedToken = null;
let tokenExpiresAt = 0;
async function getAccessToken() {
// Refresh 30 seconds before actual expiry
if (cachedToken && Date.now() < tokenExpiresAt - 30_000) {
return cachedToken;
}
const res = await fetch('https://accounts.example.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
scope: 'api:read api:write',
}),
});
const data = await res.json();
cachedToken = data.access_token;
tokenExpiresAt = Date.now() + (data.expires_in * 1000);
return cachedToken;
}
Fehler, die Entwickler tatsächlich machen
Tokens in localStorage speichern
Jede XSS-Vulnerabilität – in Ihrem eigenen Code, einer Abhängigkeit, einem Tag-Manager-Script – kann alles in localStorage lesen. Für SPAs: Speichern Sie das Zugriffstoken in der Speicherung (eine modulare Variable, die beim Neuladen verschwindet). Verwenden Sie httpOnly-Cookies für Refresh-Tokens, wenn Sie einen Backend-Server haben, der sie setzen kann. JavaScript kann httpOnly-Cookies nicht lesen.
Verwendung des impliziten Flows
Der implizite Flow gibt die Tokens direkt im URL-Fragment (#access_token=...) zurück. Diese Tokens landen in der Browsergeschichte, Serverzugriffsprotokollen und Referer-Header. Er wurde in RFC 9700 abgeschafft. Es gibt keinen Grund, den impliziten Flow für neues Code zu verwenden. Verwenden Sie PKCE.
Überspringen der State-Validierung
Ohne state Wenn die Validierung auf der Rückruf-URL übersprungen wird, kann ein Angreifer eine Umleitungs-URL erstellen, die einen OAuth-Flow mit seinem eigenen Autorisierungscode abschließt. Das Ergebnis: Das Konto des Benutzers wird mit der Identität des Angreifers verknüpft. Erstellen Sie es neu pro Flow, speichern Sie es in der Sitzung und überprüfen Sie es bei der Rückruf-URL.
client_secret in Frontend-Code zu stellen
Es gibt keine Geheimnisse, die in einem Browser leben. Minifizierung versteckt sie nicht. Verdeckung schützt sie nicht. Wenn Ihr Laufzeitumfeld ein Browser oder eine Mobilanwendung ist, haben Sie einen öffentlichen Client – verwenden Sie PKCE und lassen Sie den client_secret komplett aus. Das ist kein Workaround; es ist, wie der Spezifikation vorgesehen, wie öffentliche Clients funktionieren sollen.
Nicht proaktiv die Ablaufzeit der Token behandeln
Jedes Zugriffstoken hat einen expires_in Wert. Wenn Sie ein Token halten, bis es mit einer 401 fehlschlägt und dann erneut authentifizieren, stoßen Benutzer auf mysteriöse Fehler. Überprüfen Sie die Ablaufzeit vor jeder Anfrage, aktualisieren Sie proaktiv (30 Sekunden vor Ablauf ist ein vernünftiger Puffer) und behandeln Sie den seltenen Fall, dass ein Refresh-Token selbst abgelaufen ist.
Tokens während der Arbeit inspizieren
Die meisten OAuth-Anbieter geben JWTs als Zugriffstoken aus. Der Payload ist base64url-gekennzeichnet und lesbar ohne den privaten Schlüssel – nur die Signatur benötigt den Schlüssel zur Überprüfung. Wenn Sie einen Flow debuggen und die Ansprüche, Berechtigungen oder Ablaufzeit in einem Token sehen möchten, fügen Sie es in das JWT-Decoder.
Ein, wenn Sie manuell PKCE testen und überprüfen müssen, was ein base64url-gekennzeichnetes code_challenge entdecodiert, verwendet der Base64-Converter Standard- und URL-sichere Varianten.
Die kurze Version
Eine Frage bestimmt den richtigen Flow: Hat Ihr Laufzeitumfeld einen sicheren Ort, um ein Geheimnis zu speichern?
- Backend-Server → Authorization Code oder Client Credentials (Geheimnis bleibt auf dem Server)
- Browser oder Mobilanwendung → Authorization Code + PKCE (kein Geheimnis überhaupt)
- Kein Benutzer beteiligt → Client Credentials
PKCE funktioniert für jeden Flow mit Umleitung – es gibt keinen Nachteil, es zu verwenden, selbst wenn Ihr Anbieter es derzeit nicht erfordert. OAuth 2.1 wird es erfordern.
Erweiterungen installieren
IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche
恵 Die Anzeigetafel ist eingetroffen!
Anzeigetafel ist eine unterhaltsame Möglichkeit, Ihre Spiele zu verfolgen. Alle Daten werden in Ihrem Browser gespeichert. Weitere Funktionen folgen in Kürze!
Unverzichtbare Tools
Alle Neuheiten
AlleAktualisieren: Unser neuestes Werkzeug hinzugefügt am Juni 12, 2026
