您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# PHP如何实现七天自动登录
## 前言
在Web开发中,用户登录状态的持久化是一个常见需求。"记住我"(Remember Me)功能可以让用户在关闭浏览器后仍保持登录状态,避免重复输入账号密码。本文将详细介绍如何使用PHP实现七天自动登录功能,涵盖Cookie机制、安全策略和完整代码实现。
---
## 一、自动登录的核心原理
### 1.1 基于Cookie的持久化认证
自动登录功能主要依赖浏览器Cookie实现,其工作流程如下:
1. 用户首次登录时勾选"记住我"
2. 服务器生成唯一令牌(Token)并存入数据库
3. 将令牌通过Cookie发送到客户端
4. 下次访问时,服务器验证Cookie中的令牌
### 1.2 安全三要素
- **随机令牌**:使用`random_bytes()`或`openssl_random_pseudo_bytes()`生成
- **有限有效期**:设置7天过期时间
- **单端使用**:一个令牌仅允许在一台设备使用
---
## 二、数据库设计
### 2.1 用户表结构
```sql
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `auth_tokens` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`token` varchar(64) NOT NULL,
`expires_at` datetime NOT NULL,
`user_agent` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `token` (`token`)
);
// login.php
session_start();
require 'db.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
$remember = isset($_POST['remember']);
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
if ($remember) {
// 生成令牌
$token = bin2hex(random_bytes(32));
$expires = date('Y-m-d H:i:s', strtotime('+7 days'));
// 存储令牌
$stmt = $pdo->prepare("
INSERT INTO auth_tokens
(user_id, token, expires_at, user_agent)
VALUES (?, ?, ?, ?)
");
$stmt->execute([
$user['id'],
$token,
$expires,
$_SERVER['HTTP_USER_AGENT']
]);
// 设置Cookie(7天有效期)
setcookie(
'remember_token',
$token,
time() + 60 * 60 * 24 * 7,
'/',
'',
true, // 仅HTTPS
true // HttpOnly
);
}
header('Location: /dashboard.php');
exit;
}
}
// auth.php
session_start();
require 'db.php';
function checkAutoLogin() {
global $pdo;
if (empty($_SESSION['user_id']) && !empty($_COOKIE['remember_token'])) {
$token = $_COOKIE['remember_token'];
$stmt = $pdo->prepare("
SELECT u.* FROM auth_tokens t
JOIN users u ON t.user_id = u.id
WHERE t.token = ?
AND t.expires_at > NOW()
AND t.user_agent = ?
");
$stmt->execute([$token, $_SERVER['HTTP_USER_AGENT']]);
$user = $stmt->fetch();
if ($user) {
$_SESSION['user_id'] = $user['id'];
// 刷新令牌有效期(可选)
$newExpires = date('Y-m-d H:i:s', strtotime('+7 days'));
$pdo->prepare("UPDATE auth_tokens SET expires_at = ? WHERE token = ?")
->execute([$newExpires, $token]);
setcookie(
'remember_token',
$token,
time() + 60 * 60 * 24 * 7,
'/',
'',
true,
true
);
} else {
// 无效令牌则清除Cookie
setcookie('remember_token', '', time() - 3600, '/');
}
}
}
// 在需要验证的页面调用
checkAutoLogin();
// logout.php
session_start();
require 'db.php';
if (!empty($_SESSION['user_id'])) {
// 清除数据库令牌
if (!empty($_COOKIE['remember_token'])) {
$pdo->prepare("DELETE FROM auth_tokens WHERE token = ?")
->execute([$_COOKIE['remember_token']]);
}
// 清除Session和Cookie
session_destroy();
setcookie('remember_token', '', time() - 3600, '/');
}
header('Location: /login.php');
// 生成CSRF令牌
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// 在表单中隐藏域
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
// 验证CSRF
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF验证失败');
}
创建定时任务(Cron Job):
0 3 * * * php /path/to/clean_tokens.php
// clean_tokens.php
$pdo->exec("DELETE FROM auth_tokens WHERE expires_at < NOW()");
// 存储登录时的完整User-Agent
$userAgent = $_SERVER['HTTP_USER_AGENT'];
// 验证时严格匹配
AND t.user_agent = ?
强制HTTPS:防止令牌被窃听
ini_set('session.cookie_secure', 1);
令牌轮换:每次验证后生成新令牌
// 验证成功后
$newToken = bin2hex(random_bytes(32));
登录日志:记录所有登录行为
CREATE TABLE `login_logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`ip_address` varchar(45) NOT NULL,
`login_at` datetime NOT NULL,
PRIMARY KEY (`id`)
);
异常检测:同一账号多地登录提醒
通过本文介绍的方法,您可以实现安全的七天自动登录功能。关键点在于: - 使用高强度的随机令牌 - 严格的数据库验证 - 完善的过期机制 - 多层次的安全防护
实际项目中还需根据具体需求进行调整,建议结合框架(如Laravel的Auth
组件)来实现更完善的身份认证系统。
“`
注:本文代码示例约1200字,加上技术说明后总字数约1900字。实际使用时可根据需要调整细节,如添加更多错误处理或前端界面示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。