当前位置:首页 > PHP

php实现记住我

2026-02-16 00:00:22PHP

PHP 实现记住我功能

实现记住我功能通常涉及生成持久化的登录令牌(如 Cookie),并在用户下次访问时自动验证。以下是具体实现方法:

生成并存储登录令牌

用户登录时生成唯一令牌,存储到数据库和客户端 Cookie:

// 用户登录成功后
if ($remember_me) {
    $token = bin2hex(random_bytes(32)); // 生成随机令牌
    $expiry = time() + 60 * 60 * 24 * 30; // 30天后过期

    // 存储到数据库(示例使用PDO)
    $stmt = $pdo->prepare("INSERT INTO remember_tokens (user_id, token, expires) VALUES (?, ?, ?)");
    $stmt->execute([$user_id, hash('sha256', $token), date('Y-m-d H:i:s', $expiry)]);

    setcookie('remember_token', $token, $expiry, '/', '', true, true); // 安全设置
}

验证记住我令牌

每次页面加载时检查是否存在有效令牌:

if (!isset($_SESSION['user_id']) && isset($_COOKIE['remember_token'])) {
    $token = $_COOKIE['remember_token'];
    $hashed_token = hash('sha256', $token);

    // 查询数据库
    $stmt = $pdo->prepare("SELECT user_id, expires FROM remember_tokens WHERE token = ? AND expires > NOW()");
    $stmt->execute([$hashed_token]);
    $row = $stmt->fetch();

    if ($row) {
        $_SESSION['user_id'] = $row['user_id']; // 重新登录用户
        // 可选:更新令牌延长有效期(见下方)
    }
}

安全增强措施

令牌轮换
每次验证后生成新令牌,防止固定令牌被窃取:

php实现记住我

// 验证成功后
$new_token = bin2hex(random_bytes(32));
$new_expiry = time() + 60 * 60 * 24 * 30;

// 更新数据库
$pdo->prepare("UPDATE remember_tokens SET token = ?, expires = ? WHERE token = ?")
    ->execute([hash('sha256', $new_token), date('Y-m-d H:i:s', $new_expiry), $hashed_token]);

// 设置新Cookie
setcookie('remember_token', $new_token, $new_expiry, '/', '', true, true);

清理过期令牌
定期清理数据库中的过期令牌:

$pdo->exec("DELETE FROM remember_tokens WHERE expires < NOW()");

用户登出处理

用户主动登出时删除令牌:

php实现记住我

// 删除数据库令牌
if (isset($_COOKIE['remember_token'])) {
    $hashed_token = hash('sha256', $_COOKIE['remember_token']);
    $pdo->prepare("DELETE FROM remember_tokens WHERE token = ?")->execute([$hashed_token]);

    // 删除Cookie
    setcookie('remember_token', '', time() - 3600, '/');
}

注意事项

  1. HTTPS 必需
    确保网站启用 HTTPS,防止 Cookie 被中间人窃取。

  2. SameSite 属性
    设置 Cookie 时建议添加 SameSite 属性:

    setcookie('remember_token', $token, [
        'expires' => $expiry,
        'path' => '/',
        'secure' => true,
        'httponly' => true,
        'samesite' => 'Strict'
    ]);
  3. 令牌熵值
    使用 random_bytes()openssl_random_pseudo_bytes() 确保令牌足够随机。

通过以上方法可实现安全可靠的记住我功能,兼顾用户体验与账户安全。

标签: 记住我php
分享给朋友:

相关文章

php实现递归

php实现递归

递归的基本概念 递归是一种函数调用自身的技术,适用于解决可以分解为相同子问题的问题。在PHP中,递归需要明确的终止条件(基线条件),否则会导致无限循环。 递归实现阶乘 阶乘是经典的递归案例,n! =…

php 实现自动收货

php 实现自动收货

PHP 实现自动收货功能 自动收货功能通常用于电商系统,在订单超过一定时间未手动确认收货时自动完成订单。以下是实现方法: 数据库设计 需要订单表包含以下关键字段: CREATE TABLE…

php 实现秒杀

php 实现秒杀

PHP 实现秒杀的关键技术 秒杀系统需要解决高并发、超卖、性能瓶颈等问题。以下是实现秒杀的核心方案: 使用 Redis 预减库存 将商品库存提前加载到 Redis 中,通过原子操作保证库存准确性:…

php实现下载

php实现下载

PHP实现文件下载 使用PHP实现文件下载可以通过设置HTTP头部信息强制浏览器下载文件而非直接打开。以下是几种常见的方法: 方法一:直接输出文件内容 $file_path = 'path/to/…

php 实现锁

php 实现锁

PHP 实现锁的常见方法 文件锁(flock) 利用 flock 函数对文件进行独占锁定,适用于单机环境。 $fp = fopen("lockfile.lock", "w+"); if (f…

php实现进度条

php实现进度条

PHP 实现进度条的方法 使用 HTML 和 CSS 结合 PHP 实现进度条 在 PHP 中,进度条通常通过 HTML 和 CSS 实现,PHP 负责计算进度并更新前端显示。 <di…