Appearance
10.4 登录状态判断
登录状态判断是网站开发中的重要环节,用于控制用户对特定页面的访问权限。
基本原理
通过检查会话中存储的登录状态标志,判断用户是否已登录,从而决定是否允许访问受保护的页面。
示例代码
简单的登录状态判断
php
<?php
// 启动会话
session_start();
// 检查登录状态
if (isset($_SESSION['is_logged_in']) && $_SESSION['is_logged_in']) {
// 已登录,显示欢迎信息
echo "欢迎," . $_SESSION['username'] . "!<br>";
echo "<a href='logout.php'>退出登录</a>";
} else {
// 未登录,重定向到登录页面
header('Location: login.php');
exit;
}
?>封装登录状态检查函数
php
<?php
// auth.php
/**
* 检查用户是否已登录
* @return bool
*/
function isLoggedIn() {
// 确保会话已启动
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
return isset($_SESSION['is_logged_in']) && $_SESSION['is_logged_in'];
}
/**
* 获取当前登录用户信息
* @return array|null
*/
function getCurrentUser() {
if (!isLoggedIn()) {
return null;
}
return [
'username' => $_SESSION['username'] ?? null,
'user_id' => $_SESSION['user_id'] ?? null,
'login_time' => $_SESSION['login_time'] ?? null
];
}
/**
* 要求用户必须登录
*/
function requireLogin() {
if (!isLoggedIn()) {
// 存储当前页面,登录后重定向回来
$_SESSION['redirect_url'] = $_SERVER['REQUEST_URI'];
header('Location: login.php');
exit;
}
}
/**
* 检查会话是否过期
* @param int $expiryTime 过期时间(秒)
* @return bool
*/
function isSessionExpired($expiryTime = 1800) {
if (!isset($_SESSION['last_activity'])) {
return true;
}
return time() - $_SESSION['last_activity'] > $expiryTime;
}
/**
* 检查并处理会话过期
*/
function checkSession() {
if (isLoggedIn() && isSessionExpired()) {
// 会话过期,销毁会话
session_unset();
session_destroy();
// 存储当前页面,登录后重定向回来
$_SESSION['redirect_url'] = $_SERVER['REQUEST_URI'];
header('Location: login.php');
exit;
} else if (isLoggedIn()) {
// 更新最后活动时间
$_SESSION['last_activity'] = time();
}
}
?>在页面中使用
php
<?php
// 包含认证函数
require_once 'auth.php';
// 检查会话
checkSession();
// 要求用户登录
requireLogin();
// 获取当前用户信息
$user = getCurrentUser();
?>
<!DOCTYPE html>
<html>
<head>
<title>受保护页面</title>
</head>
<body>
<h2>受保护页面</h2>
<p>欢迎,<?php echo $user['username']; ?>!</p>
<p>登录时间: <?php echo date('Y-m-d H:i:s', $user['login_time']); ?></p>
<a href="logout.php">退出登录</a>
</body>
</html>登录后重定向到原页面
php
<?php
// login.php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 验证用户...
if (验证成功) {
// 设置会话...
// 重定向到之前尝试访问的页面
$redirectUrl = $_SESSION['redirect_url'] ?? 'dashboard.php';
unset($_SESSION['redirect_url']);
header('Location: ' . $redirectUrl);
exit;
}
}
?>前端导航栏根据登录状态显示不同内容
php
<?php
require_once 'auth.php';
?>
<nav>
<ul>
<li><a href="index.php">首页</a></li>
<?php if (isLoggedIn()): ?>
<li><a href="dashboard.php">仪表板</a></li>
<li><a href="profile.php">个人资料</a></li>
<li><a href="logout.php">退出登录</a></li>
<?php else: ?>
<li><a href="login.php">登录</a></li>
<li><a href="register.php">注册</a></li>
<?php endif; ?>
</ul>
</nav>注意事项
- 会话启动:确保在检查登录状态之前启动会话
- 重定向:使用
header('Location: ...')后必须调用exit - 会话过期:定期检查会话是否过期,提高安全性
- 用户体验:登录后重定向到用户之前尝试访问的页面
- 权限控制:根据用户角色实现更细粒度的权限控制
- 安全性:定期更新会话 ID,防止会话固定攻击
练习
- 实现一个完整的登录状态检查系统
- 添加基于角色的权限控制
- 实现登录后重定向功能
- 添加会话过期提醒
