Dragon-Knight/server/app/Auth.php

86 lines
2.2 KiB
PHP

<?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;
public function __construct()
{
}
public function login(string $identifier, string $password, bool $remember = false): bool
{
// delete the old session
if (isset($_SESSION['player_id'])) $this->logout();
// 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
if ($remember) $this->remember($id);
return true;
}
private function remember(int $id): array
{
$data = ['player_id' => $id, 'token' => token()];
Session::createOrUpdate($data); // save the token in the database, overwriting the old one if it exists
setcookie(self::COOKIE_NAME, implode('::', $data), strtotime('+30 days'), '/', '', true, true);
return $data;
}
private function logout(): void
{
if (isset($_SESSION['player_id'])) unset($_SESSION['player_id']);
if (isset($_COOKIE[self::COOKIE_NAME])) setcookie(self::COOKIE_NAME, '', time() - 86400, '/', '', true, true);
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();
}
public function good(): bool
{
// 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
$this->remember($cookie[0]);
$_SESSION['player_id'] = $cookie[0];
self::$id = $cookie[0];
return true;
}
return false;
}
}