WebsiteBaker 2.13.9 R25 is now available!
R.I.P Dietmar (luisehahne) and thank you for all your valuable work for WBhttps://forum.websitebaker.org/index.php/topic,32355.0.html
// Function to set a "remembering" cookie for the user - removed protected function remember($user_id) { return true; } // Function to check if a user has been remembered - removed protected function is_remembered() { return false; }
CREATE TABLE IF NOT EXISTS `wb_user_tokens` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `selector` char(16) NOT NULL, `hashed_validator` char(64) NOT NULL, `expires` int(11) NOT NULL, `ip` varchar(45) NOT NULL DEFAULT '', `user_agent` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY (`selector`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
selector:validator
<?phpclass RememberMe{ private $db; private $cookieName = "remember_me"; private $cookieLifetime = 86400 * 30; // 30 days public function __construct($db) { $this->db = $db; } public function createToken($user_id) { $selector = bin2hex(random_bytes(8)); $validator = bin2hex(random_bytes(32)); $hashed_validator = hash('sha256', $validator); $expires = time() + $this->cookieLifetime; $stmt = $this->db->prepare(" INSERT INTO wb_user_tokens (user_id, selector, hashed_validator, expires, ip, user_agent) VALUES (?, ?, ?, ?, ?, ?) "); $stmt->execute([ $user_id, $selector, $hashed_validator, $expires, $_SERVER['REMOTE_ADDR'] ?? '', $_SERVER['HTTP_USER_AGENT'] ?? '' ]); setcookie( $this->cookieName, $selector . ":" . $validator, $expires, "/", "", true, true ); } public function validateToken() { if (empty($_COOKIE[$this->cookieName])) { return false; } list($selector, $validator) = explode(":", $_COOKIE[$this->cookieName]); $stmt = $this->db->prepare(" SELECT id, user_id, hashed_validator, expires FROM wb_user_tokens WHERE selector = ? LIMIT 1 "); $stmt->execute([$selector]); $token = $stmt->fetch(PDO::FETCH_ASSOC); if (!$token) { return false; } if ($token['expires'] < time()) { $this->deleteTokenById($token['id']); return false; } if (hash('sha256', $validator) !== $token['hashed_validator']) { $this->deleteTokenById($token['id']); return false; } $this->deleteTokenById($token['id']); $this->createToken($token['user_id']); return $token['user_id']; } private function deleteTokenById($id) { $stmt = $this->db->prepare("DELETE FROM wb_user_tokens WHERE id = ?"); $stmt->execute([$id]); } public function deleteTokensByUser($user_id) { $stmt = $this->db->prepare("DELETE FROM wb_user_tokens WHERE user_id = ?"); $stmt->execute([$user_id]); setcookie($this->cookieName, "", time() - 3600, "/", "", true, true); }}?>
require 'RememberMe.php';$remember = new RememberMe($db);if ($login_successful) { if (!empty($_POST['remember_me'])) { $remember->createToken($user_id); } $_SESSION['user_id'] = $user_id; // redirect to dashboard...}
require 'RememberMe.php';$remember = new RememberMe($db);if (empty($_SESSION['user_id'])) { $user_id = $remember->validateToken(); if ($user_id !== false) { $_SESSION['user_id'] = $user_id; }}
$remember = new RememberMe($db);$remember->deleteTokensByUser($_SESSION['user_id']);session_destroy();
public function getTokensByUser($user_id){ $stmt = $this->db->prepare(" SELECT id, selector, hashed_validator, expires, ip, user_agent FROM wb_user_tokens WHERE user_id = ? ORDER BY expires DESC "); $stmt->execute([$user_id]); return $stmt->fetchAll(PDO::FETCH_ASSOC);}
public function deleteToken($token_id){ $stmt = $this->db->prepare("DELETE FROM wb_user_tokens WHERE id = ?"); $stmt->execute([$token_id]);}
public function getLocationFromIP($ip){ $json = @file_get_contents("https://ipapi.co/{$ip}/json/"); if ($json === false) { return "Unknown"; } $data = json_decode($json, true); return $data['country_name'] ?? 'Unknown';}
$tokens = $remember->getTokensByUser($user_id);foreach ($tokens as $token) { echo "Token ID: " . $token['id'] . "<br>"; echo "Selector: " . $token['selector'] . "<br>"; echo "IP: " . $token['ip'] . "<br>"; echo "Location: " . $remember->getLocationFromIP($token['ip']) . "<br>"; echo "User Agent: " . $token['user_agent'] . "<br>"; echo "Expires: " . date('Y-m-d H:i:s', $token['expires']) . "<br>"; echo "<a href='delete_token.php?id={$token['id']}'>Delete Token</a>"; echo "<hr>";}
require 'RememberMe.php';$remember = new RememberMe($db);if (!empty($_GET['id'])) { $remember->deleteToken($_GET['id']);}header("Location: tokens_list.php");exit;
I understand Uwe's concern, but how I see it, it is up to user weather he will check Remember me or no, of course noone will check remember me in internet cafe computer, and will check on home or office computer.