Appearance
10.3 登录与退出逻辑
登录与退出是网站中最基本的用户认证功能,需要结合表单验证、Session 管理等技术来实现。
登录流程
- 用户访问登录页面
- 用户输入用户名和密码
- 服务器验证用户凭据
- 验证成功后,创建会话并存储用户信息
- 跳转到登录后的页面
退出流程
- 用户点击退出按钮
- 服务器销毁会话
- 跳转到登录页面或首页
示例代码
登录页面
php
<?php
// login.php
session_start();
$errors = [];
// 检查是否已登录
if (isset($_SESSION['is_logged_in']) && $_SESSION['is_logged_in']) {
header('Location: dashboard.php');
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 表单验证
if (empty($_POST['username'])) {
$errors[] = '用户名不能为空';
}
if (empty($_POST['password'])) {
$errors[] = '密码不能为空';
}
if (empty($errors)) {
$username = htmlspecialchars($_POST['username']);
$password = $_POST['password'];
// 模拟用户验证
// 实际项目中应该从数据库查询并验证密码
$validUsers = [
['username' => 'admin', 'password' => password_hash('admin123', PASSWORD_DEFAULT)],
['username' => 'user', 'password' => password_hash('user123', PASSWORD_DEFAULT)]
];
$valid = false;
foreach ($validUsers as $user) {
if ($user['username'] === $username && password_verify($password, $user['password'])) {
$valid = true;
break;
}
}
if ($valid) {
// 登录成功,设置会话
$_SESSION['username'] = $username;
$_SESSION['is_logged_in'] = true;
$_SESSION['login_time'] = time();
$_SESSION['last_activity'] = time();
// 重定向到仪表板
header('Location: dashboard.php');
exit;
} else {
$errors[] = '用户名或密码错误';
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>用户登录</title>
<style>
body { font-family: Arial, sans-serif; max-width: 400px; margin: 0 auto; padding: 20px; }
.error { color: red; }
input { width: 100%; padding: 10px; margin: 5px 0; }
input[type="submit"] { background-color: #4CAF50; color: white; border: none; cursor: pointer; }
</style>
</head>
<body>
<h2>用户登录</h2>
<?php if (!empty($errors)): ?>
<div class="error">
<ul>
<?php foreach ($errors as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form action="login.php" method="post">
<label>用户名: <input type="text" name="username"></label><br>
<label>密码: <input type="password" name="password"></label><br>
<input type="submit" value="登录">
</form>
</body>
</html>仪表板页面
php
<?php
// dashboard.php
session_start();
// 检查登录状态
if (!isset($_SESSION['is_logged_in']) || !$_SESSION['is_logged_in']) {
header('Location: login.php');
exit;
}
// 更新最后活动时间
$_SESSION['last_activity'] = time();
?>
<!DOCTYPE html>
<html>
<head>
<title>仪表板</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
.header { display: flex; justify-content: space-between; align-items: center; }
.welcome { font-size: 18px; }
.logout { background-color: #f44336; color: white; padding: 10px; text-decoration: none; border-radius: 4px; }
</style>
</head>
<body>
<div class="header">
<div class="welcome">
欢迎,<?php echo $_SESSION['username']; ?>!<br>
登录时间: <?php echo date('Y-m-d H:i:s', $_SESSION['login_time']); ?>
</div>
<a href="logout.php" class="logout">退出登录</a>
</div>
<h2>仪表板</h2>
<p>这是登录后的页面,只有登录用户才能访问。</p>
</body>
</html>退出登录页面
php
<?php
// logout.php
session_start();
// 清空会话数据
session_unset();
// 销毁会话
session_destroy();
// 重定向到登录页面
header('Location: login.php');
exit;
?>会话过期检查
php
<?php
// session_check.php
function checkSessionExpiry() {
// 会话过期时间(30分钟)
$expiryTime = 30 * 60;
// 检查会话是否存在
if (!isset($_SESSION['last_activity'])) {
return false;
}
// 检查是否过期
if (time() - $_SESSION['last_activity'] > $expiryTime) {
return false;
}
// 更新最后活动时间
$_SESSION['last_activity'] = time();
return true;
}
// 在需要检查会话的页面顶部调用
session_start();
if (!checkSessionExpiry()) {
// 会话过期,销毁会话并重定向到登录页
session_unset();
session_destroy();
header('Location: login.php');
exit;
}
?>注意事项
安全性:
- 始终使用
password_hash()存储密码 - 验证用户输入,防止 SQL 注入和 XSS 攻击
- 使用 HTTPS 保护登录过程
- 始终使用
用户体验:
- 提供清晰的错误提示
- 记住用户登录状态(可选)
- 实现会话过期机制
性能:
- 避免在会话中存储大量数据
- 定期清理过期会话
安全性增强:
- 使用
session_regenerate_id()防止会话固定攻击 - 实现 CSRF 令牌保护
- 限制登录尝试次数,防止暴力破解
- 使用
练习
- 实现一个完整的登录/退出系统
- 添加记住登录功能
- 实现登录尝试限制
- 添加会话过期检查
