105 lines
2.8 KiB
PHP
105 lines
2.8 KiB
PHP
|
<?php
|
||
|
|
||
|
/*
|
||
|
This is an experimental new class for handling user auth. The idea is to rely as much as possible on PHP's native
|
||
|
session handling. When authenticated, the class will store use data in GLOBALS state.
|
||
|
*/
|
||
|
|
||
|
class Auth
|
||
|
{
|
||
|
/**
|
||
|
* Set up the auth manager; adjust PHP session settings on the fly to improve security. Starts the session for
|
||
|
* this request.
|
||
|
*/
|
||
|
public function __construct()
|
||
|
{
|
||
|
// enhance the native session's sessid cryptography
|
||
|
ini_set('session.sid_length', 64);
|
||
|
ini_set('session.sid_bits_per_character', 6);
|
||
|
|
||
|
session_set_cookie_params([
|
||
|
'lifetime' => 2592000, // 30 days
|
||
|
'path' => '/',
|
||
|
'secure' => true,
|
||
|
'httponly' => true,
|
||
|
'samesite' => 'Strict'
|
||
|
]);
|
||
|
|
||
|
session_start();
|
||
|
|
||
|
$this->validate();
|
||
|
}
|
||
|
|
||
|
private function validate(): void
|
||
|
{
|
||
|
// Check for IP address change
|
||
|
if (!isset($_SESSION['ip_address'])) {
|
||
|
$_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];
|
||
|
} elseif ($_SESSION['ip_address'] !== $_SERVER['REMOTE_ADDR']) {
|
||
|
$this->destroy(); // Possible hijacking
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
// Check for User-Agent change
|
||
|
if (!isset($_SESSION['user_agent'])) {
|
||
|
$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
|
||
|
} elseif ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {
|
||
|
$this->destroy(); // Possible hijacking
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
// Regenerate session ID periodically for security
|
||
|
if (!isset($_SESSION['last_regeneration'])) {
|
||
|
$_SESSION['last_regeneration'] = time();
|
||
|
} elseif (time() - $_SESSION['last_regeneration'] > 300) { // Every 5 minutes
|
||
|
$this->regenerate();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function login(string $username, string $password): bool
|
||
|
{
|
||
|
$user = get_user($username);
|
||
|
if ($user === false) return false;
|
||
|
|
||
|
if (password_verify($password, $user['password'])) {
|
||
|
$_SESSION['authenticated'] = true;
|
||
|
$_SESSION['user_id'] = $user['id'];
|
||
|
$_SESSION['login_time'] = time();
|
||
|
|
||
|
$this->regenerate();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public function good(): bool
|
||
|
{
|
||
|
return isset($_SESSION['authenticated']) && $_SESSION['authenticated'] === true;
|
||
|
}
|
||
|
|
||
|
public function logout(): void
|
||
|
{
|
||
|
$this->destroy();
|
||
|
}
|
||
|
|
||
|
private function regenerate(): void
|
||
|
{
|
||
|
session_regenerate_id(true);
|
||
|
$_SESSION['last_regeneration'] = time();
|
||
|
}
|
||
|
|
||
|
public function destroy(): void
|
||
|
{
|
||
|
$_SESSION = [];
|
||
|
|
||
|
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();
|
||
|
}
|
||
|
}
|