OpenID Client mit einer gepimpten Simple OpenID PHP Klasse

820 Wörter 4 Minuten Lesezeit

Bei immer mehr Projekten entsteht der Wunsch, die Benutzerauthentifizierung nicht nur per User/Passwort-Kombination durchzuführen, sondern das für den Benutzer bequeme OpenID zu implementieren. Mit der Simple OpenID PHP Class lässt sich eine Integration einer Authentifizierung mittels OpenID leicht realisieren. Eine Frischzellenkur der Klasse mit Yardis beseitigt ein Problem mit zu restriktiven OpenID Identity Providern wie Yahoo…

Aber vom Anfang an… im vorliegen Fall sollte der Login von gametools.at auf OpenID erweitert werden. Als Programmierer geht man dann auf die Suche nach einer entsprechenden Klassenbibliothek, und wird dem PHP OpenID Library zwar schnell fündig, aber obwohl die Library alle Wünsche erfüllt, ist sie doch nicht so klein und simple man es gerne für - den einen eigentlich trivialen - Loginprozeß gerne hätte… also weitersuchen, und bei PHP Classes wird man dann fündig werden – die Simple OpenID PHP Class ist klein und einfach, und wie Simple sie wirklich ist schauen wir uns hier an…

Die erste leichte Verwirrung – es sind 3 unterschiedliche Versionen im Archiv der Klasse – wurde schnell überwunden, und ein include 'class.openid.v3.php'; inkludierte die neueste Variante der Klasse in den Sourcecode des OpenID Clients.

Ein anschauliches Beispiel bei der Simple OpenID Klasse half zur schnellen Entwicklung des Clients, und kurze Zeit später war eine erfolgreiche Authentifizierung via OpenID bereits möglich.

Request an die OpenID URL senden:

include 'class.openid.v3.php';
$openid = new SimpleOpenID;
$openid->SetIdentity($_POST['openid_url']);
$openid->SetTrustRoot('http://' . $_SERVER["HTTP_HOST"]);
$openid->SetRequiredFields(array('email'));
$openid->SetOptionalFields(array('nickname'));
if ($openid->GetOpenIDServer()) {
    $openid->SetApprovedURL('http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"]);
    $openid->Redirect();
}

Leider happerte es noch bei einer Kleinigkeit – die Authentifzierung lief zwar erfolgreich, aber die für die weitere Verarbeitung notwendigen Daten wie Emailadresse oder Nickname konnten nicht extrahiert werden, und auch nach mehrmaligen durchsuchen der Klasse fand sich kein Hinweis drauf wie man an diese Daten kommen könnte. Erste Annahmen, dass es an unserem eigenen OpenID Identitiy Provider lag, konnten wir durch schnelles Debuggen widerlegen…

Nun, als Programmier denkt man manchmal offensichtlich zu kompliziert und sucht Funktionen wie $openid->GetProfile(); die aber gar nicht notwendig sind. Des Rätsels Lösung ist simpel – die ganzen Benutzerdaten werden per HTTP GET übermittel und sind ganz einfach mit $_GET['openid_...'] zugreifbar. Alle 15 Parameter sind hier in diesem PasteBin aufgelistet (bzw. kann man selbst mittels print_r(array_keys($_GET)); auflisten lassen), die gewollte Emailadresse konnten wir nun einfach mit $email=$_GET['openid_sreg_email']; auslesen.

Verarbeitung vom Response

if($_GET['openid_mode'] == 'id_res') {
    $openid = new SimpleOpenID;
    $openid->SetIdentity($_GET['openid_identity']);
    $openid_validation_result = $openid->ValidateWithServer();
    if ($openid_validation_result == true) {
        $oid=$openid->OpenID_Standarize();
        $mail=$_GET['openid_sreg_email'];
        // ... eigener Code zur Authentifizierung zB Abgleich der Variablen $oid mit der Benutzerdatenbank<br />
    }
}

Voilà, noch ein wenig drumherum programmieren, und Login sowie Neuregistrierung funktionieren perfekt mit unserem OpenID Client… theoretisch und auch praktisch… zumindest fast, denn da gibts noch Yahoo…

Yahoo ist wie einige andere auf den OpenID Zug aufgesprungen und bietet der riesigen Masse an Yahoo Usern automatisch eine OpenID Identität. Super sollte man meinen, Millionen von Leute die sich potentiell auf unserem Client einloggen könnten… können Sie aber nicht.

Warum? Unser Client ist ein voll funktionstüchtiger Client nach OpenID 1.1 Standard. Yahoo bietet Identitäten nach dem relativ neuen OpenID 2.0 Standard. Eigentlich sollte man davon ausgehen können, dass ein Standard abwärtskompatibel ist, und für unsere Anfrage nach 1.1’er Standard eine 1.1’er Rückmeldung geben könnte, aber Yahoo will hier offensichtlich einen Wechsel zu 2.0 erzwingen:

Sorry! You will not be able to login to this website as it is using an older version of the the OpenID technology. Yahoo! only supports OpenID 2.0…

Ich persönlich würde nun sagen, man verzichtet auf die Leute mit Yahoo OpenID, denn bei einem eigenen [OpenID Identitiy Provider][2] ist man selbst Herr über seine Daten und muss nicht weitere Datenkraken mit persönlichen Daten füttern, als Programmierer ist das aber vermutlich keine Option und somit brauchen wir einen Client nach OpenID 2.0 Standard.

Die erste Option, alles wieder zu verschmeissen und doch wieder zur zuvor geschassten PHP OpenID Library zurückzukehren löst alles andere als Begeisterung aus, also nochmal die Lieblingssuchmaschine anwerfen und weitersuchen… mit ein wenig Glück landet man dann im Blog von Steve Love, der genau das gleiche Problem hatte, und eine elegante Lösung parat hat… man baut die Simple OpenID PHP Klasse auf Standard 2.0 um. Was kompliziert klingt, ist es eigentlich nicht mehr wenn man das How-To von Steve durchgeht.

Im wesentlichen löst Steve das Yahoo Problem durch den Einsatz vom PHP Yadis Library, das auch im PHP OpenID Library Verwendung findet, und patcht die Simple OpenID Klasse entsprechend – genial!Die modifzierte Klasse findet sich übrigens am Ende von Steve’s Post zum Download, das Selbstpatchen entfällt somit…

Fazit: die Simple OpenID PHP Class ist einfach einzusetzen, hat aber eine gewisse Limitierung durch die fehlende Unterstützung für den OpenID 2.0 Standard. Dieser kann aber durch den Einsatz der PHP Yadis Bibliothek relativ einfach nachgerüstet werden, und ein halbwegs geübter PHP Programmierer sollte einen OpenID Login in ~30min realisiert haben.