Replace basic auth with PHP session login
This commit is contained in:
parent
d088eb90cf
commit
2ffb90d17e
4 changed files with 89 additions and 8 deletions
62
auth.php
Normal file
62
auth.php
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
const MVLOG_AUTH_CONFIG = '/etc/mvlog/auth.php';
|
||||||
|
|
||||||
|
function mvlog_session_start(): void {
|
||||||
|
if (session_status() === PHP_SESSION_ACTIVE) return;
|
||||||
|
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
|
||||||
|
session_name('MVLOGSESSID');
|
||||||
|
session_set_cookie_params([
|
||||||
|
'lifetime' => 0,
|
||||||
|
'path' => '/mvlog',
|
||||||
|
'secure' => $secure,
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Lax',
|
||||||
|
]);
|
||||||
|
session_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mvlog_auth_config(): array {
|
||||||
|
if (!is_file(MVLOG_AUTH_CONFIG)) return ['users' => []];
|
||||||
|
$config = require MVLOG_AUTH_CONFIG;
|
||||||
|
return is_array($config) ? $config : ['users' => []];
|
||||||
|
}
|
||||||
|
|
||||||
|
function mvlog_login(string $user, string $password): bool {
|
||||||
|
mvlog_session_start();
|
||||||
|
$users = mvlog_auth_config()['users'] ?? [];
|
||||||
|
$hash = is_array($users) ? ($users[$user] ?? null) : null;
|
||||||
|
if (!is_string($hash) || !password_verify($password, $hash)) return false;
|
||||||
|
session_regenerate_id(true);
|
||||||
|
$_SESSION['mvlog_user'] = $user;
|
||||||
|
$_SESSION['mvlog_login_at'] = time();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mvlog_current_user(): ?string {
|
||||||
|
mvlog_session_start();
|
||||||
|
return isset($_SESSION['mvlog_user']) && is_string($_SESSION['mvlog_user']) ? $_SESSION['mvlog_user'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mvlog_require_login(): void {
|
||||||
|
if (mvlog_current_user() !== null) return;
|
||||||
|
$next = $_SERVER['REQUEST_URI'] ?? '/mvlog/new.php';
|
||||||
|
header('Location: login.php?next=' . rawurlencode($next));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mvlog_logout(): void {
|
||||||
|
mvlog_session_start();
|
||||||
|
$_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();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mvlog_safe_next(string $next): string {
|
||||||
|
if ($next === '' || str_contains($next, "\n") || str_contains($next, "\r")) return 'new.php';
|
||||||
|
$parts = parse_url($next);
|
||||||
|
if ($parts === false || isset($parts['scheme']) || isset($parts['host'])) return 'new.php';
|
||||||
|
return $next;
|
||||||
|
}
|
||||||
23
login.php
Normal file
23
login.php
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
require __DIR__ . '/auth.php';
|
||||||
|
$err = '';
|
||||||
|
$next = mvlog_safe_next((string)($_GET['next'] ?? $_POST['next'] ?? 'new.php'));
|
||||||
|
if (mvlog_current_user() !== null) {
|
||||||
|
header('Location: ' . $next);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$user = trim((string)($_POST['user'] ?? ''));
|
||||||
|
$pass = (string)($_POST['password'] ?? '');
|
||||||
|
if (mvlog_login($user, $pass)) {
|
||||||
|
header('Location: ' . $next);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$err = 'Invalid username or password.';
|
||||||
|
}
|
||||||
|
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
|
||||||
|
?>
|
||||||
|
<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>MVLog Login</title><link rel="stylesheet" href="style.css"></head><body>
|
||||||
|
<header class="site-header"><a class="brand" href="index.php"><h1>MVLog Admin</h1><p>Bubulescu.Org</p></a></header>
|
||||||
|
<main><section><h2>Log in</h2><?php if($err): ?><div class="err"><?=h($err)?></div><?php endif; ?><form method="post" autocomplete="on"><input type="hidden" name="next" value="<?=h($next)?>"><label>Username<input name="user" autocomplete="username" required autofocus></label><label>Password<input type="password" name="password" autocomplete="current-password" required></label><button type="submit">Log in</button></form></section></main>
|
||||||
|
</body></html>
|
||||||
10
logout.php
10
logout.php
|
|
@ -1,12 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
|
require __DIR__ . '/auth.php';
|
||||||
setcookie('mvlog_realm', bin2hex(random_bytes(8)), [
|
mvlog_logout();
|
||||||
'expires' => time() + 31536000,
|
|
||||||
'path' => '/mvlog',
|
|
||||||
'secure' => $secure,
|
|
||||||
'httponly' => true,
|
|
||||||
'samesite' => 'Lax',
|
|
||||||
]);
|
|
||||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||||
header('Location: index.php');
|
header('Location: index.php');
|
||||||
exit;
|
exit;
|
||||||
|
|
|
||||||
2
new.php
2
new.php
|
|
@ -1,4 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
require __DIR__ . '/auth.php';
|
||||||
|
mvlog_require_login();
|
||||||
$config = require __DIR__ . "/config.php";
|
$config = require __DIR__ . "/config.php";
|
||||||
foreach (["videos_dir", "thumbs_dir", "uploads_dir"] as $d) if (!is_dir($config[$d])) mkdir($config[$d], 0775, true);
|
foreach (["videos_dir", "thumbs_dir", "uploads_dir"] as $d) if (!is_dir($config[$d])) mkdir($config[$d], 0775, true);
|
||||||
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, "UTF-8"); }
|
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, "UTF-8"); }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue