Keine Werbung mögen? Gehen Werbefrei Heute

OAuth 2.0 Flows Authorization Code, PKCE, and Client Credentials

Aktualisiert am

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.

OAuth 2.0 Flows: Authorization Code, PKCE, and Client Credentials 1
ANZEIGE Entfernen?

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.

FlowWann wird es verwendetBenutzer beteiligt?Bedarf an client_secret?
Authorization CodeWebanwendung mit einem Backend-ServerJaJa – bleibt auf dem Server
Authorization Code + PKCESPA, Mobilanwendung, jeder öffentliche ClientJaNEIN
Client CredentialsServer-zu-Server (kein Benutzer)NEINJa – 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.

Möchten Sie werbefrei genießen? Werde noch heute werbefrei

Erweiterungen installieren

IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche

Zu Chrome-Erweiterung Zu Kantenerweiterung Zu Firefox-Erweiterung Zu Opera-Erweiterung

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!

ANZEIGE Entfernen?
ANZEIGE Entfernen?
ANZEIGE Entfernen?

Nachrichtenecke mit technischen Highlights

Beteiligen Sie sich

Helfen Sie uns, weiterhin wertvolle kostenlose Tools bereitzustellen

Kauf mir einen Kaffee
ANZEIGE Entfernen?