记住密码 php实现
实现记住密码功能的方法
使用PHP实现记住密码功能通常涉及生成并存储持久性登录凭证(如Cookie),以下是一种常见实现方式:
设置记住密码Cookie
用户登录时若勾选"记住我",生成长期有效的Token并存储:

if ($login_success && isset($_POST['remember_me'])) {
$selector = bin2hex(random_bytes(8));
$validator = bin2hex(random_bytes(32));
$token = $selector . ':' . $validator;
$hashedValidator = password_hash($validator, PASSWORD_DEFAULT);
$expires = time() + 86400 * 30; // 30天有效期
// 存储到数据库
$stmt = $pdo->prepare("INSERT INTO auth_tokens (user_id, selector, hashed_validator, expires) VALUES (?, ?, ?, ?)");
$stmt->execute([$user_id, $selector, $hashedValidator, date('Y-m-d H:i:s', $expires)]);
// 设置Cookie
setcookie('remember_token', $token, $expires, '/', '', true, true);
}
验证记住密码的Token
每次页面加载时检查是否存在记住密码的Cookie:

if (!isset($_SESSION['user_id']) && isset($_COOKIE['remember_token'])) {
list($selector, $validator) = explode(':', $_COOKIE['remember_token']);
$stmt = $pdo->prepare("SELECT * FROM auth_tokens WHERE selector = ? AND expires >= NOW()");
$stmt->execute([$selector]);
$token = $stmt->fetch();
if ($token && password_verify($validator, $token['hashed_validator'])) {
$_SESSION['user_id'] = $token['user_id'];
// 可选:更新Token延长有效期
$newValidator = bin2hex(random_bytes(32));
$newHashedValidator = password_hash($newValidator, PASSWORD_DEFAULT);
$newToken = $selector . ':' . $newValidator;
setcookie('remember_token', $newToken, time() + 86400 * 30, '/', '', true, true);
$stmt = $pdo->prepare("UPDATE auth_tokens SET hashed_validator = ? WHERE id = ?");
$stmt->execute([$newHashedValidator, $token['id']]);
}
}
安全注意事项
实现记住密码功能时需注意以下安全措施:
- 始终使用HTTPS传输Cookie
- 设置Cookie的HttpOnly和Secure属性
- Token应包含随机生成的selector和validator两部分
- validator需哈希后存储,类似密码存储方式
- 定期清理过期的Token记录
- 提供用户手动注销所有设备的功能
数据库表结构示例
用于存储Token的数据库表建议结构:
CREATE TABLE auth_tokens (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
selector VARCHAR(16) NOT NULL,
hashed_validator VARCHAR(255) NOT NULL,
expires DATETIME NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
UNIQUE KEY (selector)
);
这种实现方式比直接存储用户名密码更安全,且允许用户在不同设备间管理登录状态。






