Voraussetzung ist, das man die ID des zu löschenden Eintrages kennt.
$statement = $pdo->prepare("DELETE FROM feinstaub WHERE id = ?"); $statement->execute(array($id)); if ($statement->execute()) { echo "Der DB-Eintrag wurde erfolgreich gelöscht!"; } else { echo "Bitte den Administrator informieren!"; }Yubikey als 2FA
-
Heute mal was Praktisches
Wir haben eine Webseite, dazu benutzen wir ein Loginscript. Diese Funktion möchten wir jetzt um einen 2FA erweitern. Da ich schon viele Jahre einen Yubikey benutze, wollte ich das natürlich einbauen.
Der Yubikey kann mit zwei Slots bestückt werden, Standard ist auf Slot 1 ein OTP, Slot 2 habe ich mit einem statischen Passwort versehen, doch das soll hier ja nicht das Thema sein.
Also, der Plan
Nach dem Login mit EMail und Passwort kommt man auf eine Seite wo man nach dem Yubikey gefragt wird. Dazu muss dieser eingesteckt werden und die Taste berührt werden. Wenn der OTP zu dem vorher angelegten YubiKey passt, erfolgt der Login, wenn nicht wird er verweigert.
Installation
Komplette Installation, da ich nach Serverumzug danach gesucht habe, hier in drei Zeilen! (Update: 21. August 2019)
apt install php-pear wget https://developers.yubico.com/php-yubico/Releases/Auth_Yubico-2.6.tgz pear install Auth_Yubico-2.6.tgz
Für PHP-Coder gibt es auf der folgenden Seite Informationen zu der Installation und Nutzung.
https://developers.yubico.com/php-yubico/Ich hatte so ein wenig Probleme, das vernünftig zu installieren, kann mich aber nicht mehr an alles so genau erinnern. Mist, sonst schreibe ich immer alles mit. Es ging um ein paar .dll Dateien, die im falschen Verzeichnis lagen. Ein kopieren von Hand hatte dieses Problem aber gelöst. Also, nicht aufgeben, mal die Fehlermeldungen genau lesen.
Solltet Ihr mal eine neue Version von Auth_Yubico installieren wollen, so müsst Ihr erst die alte deinstallieren.
root@one /home/frank # pear install Auth_Yubico-2.6.tgz Skipping package "pear/Auth_Yubico", already installed as version 2.5 No valid packages found install failed
So, sah das aus.
root@one /home/frank # pear install Auth_Yubico-2.6.tgz install ok: channel://pear.php.net/Auth_Yubico-2.6
Erledigt
Beispiel Code
Hier das Beispiel von Yubico zur Implementierung in den Code.
<?php require_once 'Auth/Yubico.php'; $otp = "ccbbddeertkrctjkkcglfndnlihhnvekchkcctif"; # Generate a new id+key from https://upgrade.yubico.com/getapikey $yubi = new Auth_Yubico('42', 'FOOBAR='); $auth = $yubi->verify($otp); if (PEAR::isError($auth)) { print "<p>Authentication failed: " . $auth->getMessage(); print "<p>Debug output from server: " . $yubi->getLastResponse(); } else { print "<p>You are authenticated!"; } ?>
Mich hatte mal interessiert, wo das Auth/Yubico.php auf dem Server liegt
root@one / # find -name Yubico.php ./usr/share/php/Auth/Yubico.php
Gut, der Code sollte soweit ja kein Problem sein.
$otp = "ccbbddeertkrctjkkcglfndnlihhnvekchkcctif";
Das ist der OTP, den man bekommt wenn man die Taste auf dem Yubikey berührt.
$yubi = new Auth_Yubico('42', 'FOOBAR=');
Um die API von Yubico benutzen zu können, muss man sich einen Account anlegen. Auf https://upgrade.yubico.com/getapikey bekommt man die benötigten Daten.
Der Rest sollte selbsterklärend sein.
Praxis
Auswertung
// Auswertung!! if(isset($_GET['login'])) { $email = **gekürzt**; $yubikey = htmlspecialchars($_POST['yubikey']); $statement = $pdo->prepare("SELECT * FROM users WHERE email = :email"); $result = $statement->execute(array('email' => $email)); $user = $statement->fetch(); // YubiKey Auswertung if(!$user['otpKey'] == NULL) { $otp = strtolower($yubikey); require_once 'Auth/Yubico.php'; # Generate a new id+key from https://upgrade.yubico.com/getapikey $yubi = new Auth_Yubico('******', '******'); $auth = $yubi->verify($otp); if (PEAR::isError($auth)) { //Error Auswertung header('Location: yubi_error.php'); die(); } else { //Erfolg **GEKÜRZT** } header('Location: /ziel.php'); die(); } } } ?>
Kurzerklärung
Was macht man? Der User loggt sich mit EMail & PW ein, man merkt sicht die EMail, wenn das PW stimmt. Springt auf die Yubikey Abfrage. Dort liest man den OTP ein, schaut in der Datenbank nach dem hinterlegten Yubikey. Wenn hinterlegt ist, wird der OTP auf Gültigkeit abgefragt. Danach erfolgt der Login, wenn nicht kommt einen Fehlermeldung.
Wie ich das gelöst habe, mit der Speicherung des Yubikeys im Backend, erkläre ich im nächsten Beitrag.
Es sind oben im Code ein paar Sachen gekürzt. Wer damit Probleme hat, kann mir gerne eine PN schreiben, ich erkläre das Gerne. Möchte das aber hier nicht öffentlich stehen haben, weil ich nicht 100% weiß ob das perfekter Code ist
-
Die ersten 12 Stellen eines Yubikeys sind immer gleich. Diese 12 Stellen speichern wir in einer Datenbank.
$otp = substr ($otpKey, 0, 12);
In der Datenbank speichern.
//SQL $statement = $pdo->prepare("UPDATE users SET otpKey = :otpKey_neu WHERE id = :id"); $statement->execute(array('otpKey_neu' => $otp, 'id' => $userid)); //Überwachung auf Erfolg if ($statement->execute()) { // DB Eintrag erfolgreich geschrieben echo "YubiKey Passwort erfolgreich gespeichert!"; } else { echo "Datenbank Fehler! Bitte informieren Sie den Administrator."; }
Ich hoffe, es hilft dem ein oder anderen sich mit diesem Thema etwas zu beschäftigen.