2024-07-15 18:05:35 -05:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
|
|
|
Security, and especially authentication, is not a simple matter.
|
|
|
|
There's a lot to learn here.
|
|
|
|
*/
|
|
|
|
|
|
|
|
class Auth
|
|
|
|
{
|
|
|
|
// name of the remember me cookie
|
|
|
|
private const COOKIE_NAME = 'dragon-of-memory';
|
|
|
|
|
|
|
|
// id of the player
|
|
|
|
public static int $id = 0;
|
|
|
|
|
2024-07-15 19:54:50 -05:00
|
|
|
public function login(string $identifier, string $password, bool $remember = false): bool
|
2024-07-15 18:05:35 -05:00
|
|
|
{
|
|
|
|
// delete the old session
|
2024-07-15 19:54:50 -05:00
|
|
|
if (isset($_SESSION['player_id'])) $this->logout();
|
2024-07-15 18:05:35 -05:00
|
|
|
|
|
|
|
// get the player by their username
|
|
|
|
$id = Player::validateCredentials($identifier, $password);
|
|
|
|
if ($id === false) return false;
|
|
|
|
|
|
|
|
// set the session
|
|
|
|
$_SESSION['player_id'] = $id;
|
|
|
|
self::$id = $id;
|
|
|
|
|
|
|
|
// set the remember me cookie
|
2024-07-15 19:54:50 -05:00
|
|
|
if ($remember) $this->remember($id);
|
2024-07-15 18:05:35 -05:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-07-17 16:12:57 -05:00
|
|
|
private function remember(int $id): array
|
2024-07-15 18:05:35 -05:00
|
|
|
{
|
|
|
|
$data = ['player_id' => $id, 'token' => token()];
|
|
|
|
|
2024-07-17 16:12:57 -05:00
|
|
|
Session::createOrUpdate($data); // save the token in the database, overwriting the old one if it exists
|
2024-07-15 18:05:35 -05:00
|
|
|
setcookie(self::COOKIE_NAME, implode('::', $data), strtotime('+30 days'), '/', '', true, true);
|
|
|
|
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
2024-07-17 18:41:34 -05:00
|
|
|
public function logout(): void
|
2024-07-15 18:05:35 -05:00
|
|
|
{
|
|
|
|
if (isset($_SESSION['player_id'])) unset($_SESSION['player_id']);
|
|
|
|
if (isset($_COOKIE[self::COOKIE_NAME])) setcookie(self::COOKIE_NAME, '', time() - 86400, '/', '', true, true);
|
2024-07-17 16:12:57 -05:00
|
|
|
if (ini_get("session.use_cookies")) {
|
|
|
|
$params = session_get_cookie_params();
|
|
|
|
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
|
|
|
|
}
|
|
|
|
session_destroy();
|
2024-07-15 18:05:35 -05:00
|
|
|
}
|
|
|
|
|
2024-07-15 19:54:50 -05:00
|
|
|
public function good(): bool
|
2024-07-15 18:05:35 -05:00
|
|
|
{
|
|
|
|
// if our player_id session still exists, carry on
|
|
|
|
if (isset($_SESSION['player_id'])) {
|
|
|
|
self::$id = $_SESSION['player_id'];
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if a remember me cookie exists, try to validate it
|
|
|
|
if (isset($_COOKIE[self::COOKIE_NAME])) {
|
|
|
|
$cookie = explode('::', $_COOKIE[self::COOKIE_NAME]); // player_id::token
|
|
|
|
|
|
|
|
// try to validate the token
|
|
|
|
if (!Session::validate($cookie[0], $cookie[1])) return false; // the token is invalid
|
|
|
|
|
|
|
|
// token is valid, refresh cookie and assign session
|
2024-07-15 19:54:50 -05:00
|
|
|
$this->remember($cookie[0]);
|
2024-07-15 18:05:35 -05:00
|
|
|
$_SESSION['player_id'] = $cookie[0];
|
|
|
|
self::$id = $cookie[0];
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2024-07-17 22:11:45 -05:00
|
|
|
|
|
|
|
public static function boot(): void
|
|
|
|
{
|
|
|
|
// adjust session settings
|
|
|
|
ini_set('session.gc_maxlifetime', 604800); // 1 week in seconds
|
|
|
|
ini_set('session.cookie_lifetime', 604800); // 1 week in seconds
|
|
|
|
|
|
|
|
// ensure secure session handling
|
|
|
|
ini_set('session.use_strict_mode', 1);
|
|
|
|
ini_set('session.cookie_httponly', 1);
|
|
|
|
ini_set('session.cookie_secure', 1); // only if using HTTPS
|
|
|
|
|
|
|
|
// start the session
|
|
|
|
session_start();
|
|
|
|
|
|
|
|
// regenerate session ID to prevent session fixation
|
|
|
|
if (!isset($_SESSION['initiated'])) {
|
|
|
|
session_regenerate_id(true);
|
|
|
|
$_SESSION['initiated'] = true;
|
|
|
|
}
|
|
|
|
}
|
2024-07-17 12:58:13 -05:00
|
|
|
}
|