Start · Sprachen · PHP · Referenz · OAuthProvider

OAuthProvider

Klasse

Klasse zur serverseitigen Implementierung eines OAuth 1.0-Providers, der Zugriffstoken und Anfragen validiert.

seit PHP 5.1.0 Kategorie: http

Signatur

class OAuthProvider

Beschreibung

OAuthProvider ist Teil der PHP-OAuth-Erweiterung (PECL oauth) und ermöglicht es, einen vollständigen OAuth 1.0-Provider auf der Serverseite zu implementieren. Mit dieser Klasse können Sie eingehende OAuth-signierte Anfragen prüfen, Zugriffstoken und Request-Token ausstellen sowie die gesamte OAuth-Verhandlung (Handshake) steuern.

Die Klasse arbeitet mit sogenannten Callback-Funktionen: Sie registrieren Callbacks für die Prüfung von Consumer-Key, Token und Timestamp/Nonce. Für jede eingehende Anfrage ruft OAuthProvider diese Callbacks auf und erwartet, dass die Anwendung die Gültigkeit der Daten selbst überprüft – typischerweise gegen eine Datenbank. Damit bleibt die Datenhaltung vollständig in der Kontrolle des Entwicklers.

Typische Einsatzszenarien sind REST-APIs, bei denen Drittanwendungen im Namen von Benutzern handeln (z. B. Lesen/Schreiben in einem Social-Network oder Cloud-Dienst). OAuthProvider übernimmt dabei die kryptografische Signaturvalidierung (HMAC-SHA1, RSA-SHA1, PLAINTEXT) und die Protokolllogik, während Speicherung und Berechtigungsprüfung der Anwendung obliegen.

Hinweis: Diese Klasse setzt die PECL-Erweiterung oauth voraus (pecl install oauth) und implementiert OAuth 1.0 bzw. 1.0a. Für OAuth 2.0 existieren separate Bibliotheken.

Parameter

Name Typ Default Beschreibung
$params_array array [] Optionales assoziatives Array mit vordefinierten OAuth-Parametern, die der Provider verwenden soll (z. B. ['oauth_callback' => 'oob']). Wird häufig leer gelassen.

Beispiele

Einfache OAuth-Provider-Initialisierung mit Callbacks

<?php
// PECL-oauth-Erweiterung muss installiert sein

function checkConsumer(OAuthProvider $provider): int
{
    // Consumer-Key gegen Datenbank prüfen
    if ($provider->consumer_key === 'mein_consumer_key') {
        $provider->consumer_secret = 'mein_consumer_secret';
        return OAUTH_OK;
    }
    return OAUTH_CONSUMER_KEY_UNKNOWN;
}

function checkToken(OAuthProvider $provider): int
{
    // Zugriffstoken gegen Datenbank prüfen
    if ($provider->token === 'gueltiger_token') {
        $provider->token_secret = 'token_secret';
        return OAUTH_OK;
    }
    return OAUTH_TOKEN_REJECTED;
}

function checkNonce(OAuthProvider $provider): int
{
    // Nonce auf Wiederverwendung prüfen (Replay-Attack-Schutz)
    // Hier vereinfacht: immer OK
    return OAUTH_OK;
}

try {
    $oauthProvider = new OAuthProvider();
    $oauthProvider->consumerHandler('checkConsumer');
    $oauthProvider->timestampNonceHandler('checkNonce');
    $oauthProvider->tokenHandler('checkToken');

    // OAuth-Parameter aus dem aktuellen Request prüfen
    $oauthProvider->checkOAuthRequest();

    echo 'Anfrage erfolgreich autorisiert.';
} catch (OAuthException $e) {
    http_response_code(401);
    echo 'OAuth-Fehler: ' . $e->getMessage();
}
Anfrage erfolgreich autorisiert.

Request-Token ausstellen

<?php
// Hilfsmethode zum Generieren eines sicheren Tokens
function generateToken(int $length = 32): string
{
    return bin2hex(random_bytes($length));
}

function checkConsumerForRequestToken(OAuthProvider $provider): int
{
    // In einer echten Anwendung: Datenbankabfrage
    $knownConsumers = [
        'app_key_123' => 'app_secret_456',
    ];

    if (isset($knownConsumers[$provider->consumer_key])) {
        $provider->consumer_secret = $knownConsumers[$provider->consumer_key];
        return OAUTH_OK;
    }
    return OAUTH_CONSUMER_KEY_UNKNOWN;
}

try {
    $provider = new OAuthProvider();
    $provider->consumerHandler('checkConsumerForRequestToken');
    $provider->timestampNonceHandler(function (OAuthProvider $p): int {
        return OAUTH_OK;
    });
    // Kein Token-Handler nötig für Request-Token-Endpoint
    $provider->isRequestTokenEndpoint(true);
    $provider->checkOAuthRequest();

    // Request-Token erzeugen und speichern
    $requestToken  = generateToken();
    $tokenSecret   = generateToken();

    // In der Datenbank speichern:
    // saveRequestToken($provider->consumer_key, $requestToken, $tokenSecret);

    header('Content-Type: application/x-www-form-urlencoded');
    echo http_build_query([
        'oauth_token'              => $requestToken,
        'oauth_token_secret'       => $tokenSecret,
        'oauth_callback_confirmed' => 'true',
    ]);
} catch (OAuthException $e) {
    http_response_code(401);
    echo 'Fehler: ' . $e->getMessage();
}
oauth_token=...&oauth_token_secret=...&oauth_callback_confirmed=true

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Nonce-Prüfung: Der timestampNonceHandler-Callback muss jede Nonce-Timestamp-Kombination in einer Datenbank oder einem Cache (z. B. Redis) speichern und doppelte Verwendungen ablehnen, um Replay-Angriffe zu verhindern.
  • Timestamp-Toleranz: Akzeptieren Sie nur Timestamps innerhalb eines engen Zeitfensters (typisch ±5 Minuten), um ältere Anfragen abzuweisen.
  • HTTPS: OAuth 1.0 überträgt den Consumer-Secret niemals im Klartext, dennoch sollte die gesamte Kommunikation ausschließlich über HTTPS erfolgen, da PLAINTEXT-Signaturen unsicher sind.
  • Consumer-Secrets sicher speichern: Speichern Sie Consumer-Secrets gehasht oder verschlüsselt in der Datenbank.
  • Die PECL-oauth-Erweiterung wird nicht mehr aktiv gepflegt. Für neue Projekte empfehlen sich OAuth-2.0-Bibliotheken wie league/oauth2-server.

Siehe auch