Files
shuiguoji/admin/login.php
T
2026-07-23 08:58:13 +08:00

26 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
require dirname(__DIR__) . '/includes/bootstrap.php';
if (current_admin()) redirect('/admin/index.php');
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
verify_csrf();
$username = trim((string)($_POST['username'] ?? ''));
assert_auth_not_limited('admin_login', $username, 5, 900);
$stmt = db()->prepare('SELECT * FROM admins WHERE username = ?');
$stmt->execute([$username]);
$admin = $stmt->fetch();
if (!$admin || !password_verify((string)($_POST['password'] ?? ''), $admin['password_hash'])) {
record_auth_attempt('admin_login', $username, false);
throw new RuntimeException('管理员账号或密码错误。');
}
session_regenerate_id(true); $_SESSION['admin_id'] = (int)$admin['id'];
record_auth_attempt('admin_login', $username, true);
db()->prepare('UPDATE admins SET last_login_at = ? WHERE id = ?')->execute([now(), $admin['id']]);
admin_audit(db(), 'admin_login', 'admin', (int)$admin['id']);
redirect('/admin/index.php');
} catch (Throwable $e) { $error = $e instanceof RuntimeException ? $e->getMessage() : '登录失败。'; }
}
?><!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>后台登录</title><link rel="stylesheet" href="/assets/app.css?v=20260721"><link rel="stylesheet" href="/assets/admin.css?v=20260721"></head><body class="admin-login"><main><div class="admin-login-brand"><span>金</span><div><b><?=e(setting('site_name'))?></b><small>运营管理后台</small></div></div><?php if($error):?><div class="alert error"><?=e($error)?></div><?php endif;?><form method="post" class="form-stack"><input type="hidden" name="csrf" value="<?=e(csrf_token())?>"><label><span>管理员账号</span><input name="username" autocomplete="username" required autofocus></label><label><span>密码</span><input type="password" name="password" autocomplete="current-password" required></label><button class="btn primary">登录后台</button></form><a class="back-site" href="/index.php">← 返回用户端</a></main></body></html>