mirror of
https://github.com/myronblair/parkerslingshotrentals
synced 2026-06-30 17:50:31 -05:00
Fix admin login: replace PHP sessions with HMAC cookie auth
PHP sessions were unreliable on this host — the web process could write session files but LiteSpeed served cached login-page responses on the redirect, bypassing PHP entirely. Replace sessions with a self-contained signed cookie: - On login: generate random 32-byte token + expiry, sign with HMAC-SHA256 - On each request: verify signature and expiry — no filesystem reads needed - Cookie: Secure, HttpOnly, SameSite=Lax, path=/admin/, 24h expiry - admin/.htaccess: CacheEnable off + no-store headers to prevent LiteSpeed from caching admin responses Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
<IfModule LiteSpeed>
|
||||||
|
CacheEnable off
|
||||||
|
</IfModule>
|
||||||
|
Header always set Cache-Control "no-store, no-cache, must-revalidate"
|
||||||
|
Header always set Pragma "no-cache"
|
||||||
+38
-9
@@ -1,23 +1,52 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__DIR__) . '/db.php';
|
require_once dirname(__DIR__) . '/db.php';
|
||||||
ini_set('session.save_path', '/home/parkerslingshotrentals.com/sessions');
|
|
||||||
ini_set('session.cookie_httponly', 1);
|
// ── Cookie-based auth (no PHP sessions — avoids server caching/permission issues) ──
|
||||||
ini_set('session.cookie_samesite', 'Lax');
|
define('AUTH_COOKIE', 'parker_auth');
|
||||||
session_start();
|
define('AUTH_SECRET', hash('sha256', ADMIN_PASS . ADMIN_SESSION_KEY)); // not reversible
|
||||||
|
|
||||||
|
function _authToken(): string {
|
||||||
|
$t = bin2hex(random_bytes(32));
|
||||||
|
$e = time() + 86400; // 24h
|
||||||
|
$s = hash_hmac('sha256', "$t|$e", AUTH_SECRET);
|
||||||
|
return "$t.$e.$s";
|
||||||
|
}
|
||||||
|
function _verifyAuth(): bool {
|
||||||
|
$c = $_COOKIE[AUTH_COOKIE] ?? '';
|
||||||
|
$p = explode('.', $c, 3);
|
||||||
|
if (count($p) !== 3) return false;
|
||||||
|
[$t, $e, $s] = $p;
|
||||||
|
if ((int)$e < time()) return false;
|
||||||
|
return hash_equals(hash_hmac('sha256', "$t|$e", AUTH_SECRET), $s);
|
||||||
|
}
|
||||||
|
function _setAuth(): void {
|
||||||
|
$secure = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
|
||||||
|
setcookie(AUTH_COOKIE, _authToken(), [
|
||||||
|
'expires' => time() + 86400,
|
||||||
|
'path' => '/admin/',
|
||||||
|
'secure' => $secure,
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Lax',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
function _clearAuth(): void {
|
||||||
|
$secure = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
|
||||||
|
setcookie(AUTH_COOKIE, '', ['expires' => time()-3600, 'path' => '/admin/', 'secure' => $secure, 'httponly' => true, 'samesite' => 'Lax']);
|
||||||
|
}
|
||||||
|
|
||||||
$isAjax = !empty($_SERVER['HTTP_X_REQUESTED_WITH']) || (($_SERVER['HTTP_ACCEPT'] ?? '') === 'application/json');
|
$isAjax = !empty($_SERVER['HTTP_X_REQUESTED_WITH']) || (($_SERVER['HTTP_ACCEPT'] ?? '') === 'application/json');
|
||||||
|
|
||||||
// ── Auth ──────────────────────────────────────────────────────────────────────
|
// ── Auth ──────────────────────────────────────────────────────────────────────
|
||||||
if ($_POST['action'] ?? '' === 'login') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'login') {
|
||||||
if ($_POST['username'] === ADMIN_USER && password_verify($_POST['password'] ?? '', ADMIN_PASS)) {
|
if ($_POST['username'] === ADMIN_USER && password_verify($_POST['password'] ?? '', ADMIN_PASS)) {
|
||||||
$_SESSION[ADMIN_SESSION_KEY] = true;
|
_setAuth();
|
||||||
}
|
}
|
||||||
header('Location: /admin/'); exit;
|
header('Location: /admin/'); exit;
|
||||||
}
|
}
|
||||||
if ($_GET['action'] ?? '' === 'logout') {
|
if (($_GET['action'] ?? '') === 'logout') {
|
||||||
session_destroy(); header('Location: /admin/'); exit;
|
_clearAuth(); header('Location: /admin/'); exit;
|
||||||
}
|
}
|
||||||
$authed = !empty($_SESSION[ADMIN_SESSION_KEY]);
|
$authed = _verifyAuth();
|
||||||
|
|
||||||
// ── AJAX handlers ─────────────────────────────────────────────────────────────
|
// ── AJAX handlers ─────────────────────────────────────────────────────────────
|
||||||
if ($isAjax && !$authed) {
|
if ($isAjax && !$authed) {
|
||||||
|
|||||||
Reference in New Issue
Block a user