Trong quá trình phát triển ứng dụng web bằng PHP, tính năng “Nhớ mật khẩu” (remember me) luôn là một nhu cầu quen thuộc. Nó cho phép người dùng không phải đăng nhập lại mỗi khi truy cập website, nhờ vào việc lưu trữ thông tin đăng nhập tạm thời trong cookie. Tính năng này giúp cải thiện trải nghiệm người dùng, đặc biệt đối với các ứng dụng thương mại điện tử, diễn đàn hay hệ thống quản trị mà người dùng cần đăng nhập thường xuyên.
Để triển khai một cách an toàn, bạn cần kết hợp nhiều kỹ thuật: xác thực qua cơ sở dữ liệu (MySQL), mã hóa dữ liệu cookie, quản lý phiên làm việc bằng session, và kèm theo các lớp bảo mật bổ sung như token ngẫu nhiên, hashing và thời gian hết hạn. Nếu trước đây bạn đã từng tìm hiểu về giữ đăng nhập bằng Session trong PHP hoặc xây dựng chức năng phân quyền user và admin trong PHP, thì bài viết này sẽ là bước tiếp theo, giúp bạn hoàn thiện luồng xác thực người dùng với cơ chế “ghi nhớ đăng nhập”.
Nguyên lý hoạt động của tính năng “Remember Me”
Tính năng nhớ mật khẩu dựa trên cơ chế cookie của trình duyệt. Khi người dùng tick vào ô “Nhớ mật khẩu” và đăng nhập thành công, hệ thống sẽ tạo một cookie lưu trên máy người dùng. Cookie này chứa thông tin đặc biệt (thường là token), để lần sau khi người dùng quay lại, ứng dụng sẽ đọc cookie, xác thực token với dữ liệu lưu trong database, và tự động tạo session đăng nhập.
Điểm cần lưu ý:
-
Không bao giờ lưu trực tiếp mật khẩu trong cookie.
-
Cookie nên chứa một giá trị ngẫu nhiên (token), được liên kết với người dùng trong cơ sở dữ liệu.
-
Token cần được hash và có ngày hết hạn để tránh lạm dụng.
-
Khi người dùng đăng xuất, cookie phải bị xóa và token bị vô hiệu hóa trong database.
Tạo form đăng nhập có tùy chọn “Nhớ mật khẩu”
Đầu tiên, bạn cần form đăng nhập cơ bản. Form này sẽ có thêm checkbox “Remember Me” để gửi thông tin người dùng muốn lưu đăng nhập.
<form action="login.php" method="post">
<label for="username">Tên đăng nhập:</label>
<input type="text" id="username" name="username" required>
<label for="password">Mật khẩu:</label>
<input type="password" id="password" name="password" required>
<label>
<input type="checkbox" name="remember"> Nhớ mật khẩu
</label>
<button type="submit">Đăng nhập</button>
</form>
Form này đơn giản, nhưng nó sẽ là điểm khởi đầu để gửi dữ liệu username, password và trạng thái remember đến file xử lý đăng nhập.
Xử lý đăng nhập và tạo cookie
Trong file login.php, bạn sẽ xử lý logic:
- Kiểm tra thông tin người dùng trong database.
- Nếu đúng, tạo session để đăng nhập.
- Nếu người dùng tick chọn “Remember Me”, tạo token ngẫu nhiên, lưu vào database, đồng thời lưu token đó vào cookie.
<?php
session_start();
require 'db.php'; // file kết nối PDO
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
$remember = isset($_POST['remember']);
$stmt = $pdo->prepare("SELECT id, password FROM users WHERE username = :username");
$stmt->execute(['username' => $username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
// Lưu session
$_SESSION['user_id'] = $user['id'];
if ($remember) {
// Tạo token
$token = bin2hex(random_bytes(32));
$hashedToken = password_hash($token, PASSWORD_DEFAULT);
// Lưu token vào DB
$stmt = $pdo->prepare("UPDATE users SET remember_token = :token, token_expiry = DATE_ADD(NOW(), INTERVAL 30 DAY) WHERE id = :id");
$stmt->execute([
'token' => $hashedToken,
'id' => $user['id']
]);
// Lưu token gốc vào cookie
setcookie("rememberme", $user['id'] . ':' . $token, time() + (86400 * 30), "/", "", false, true);
}
header("Location: index.php");
exit;
} else {
echo "Sai tên đăng nhập hoặc mật khẩu.";
}
}
Ở đây:
-
Token được tạo bằng
random_bytesđể đảm bảo ngẫu nhiên mạnh. -
Token lưu trong DB được hash bằng
password_hashđể tăng độ an toàn. -
Cookie lưu
user_id:tokenđể lần sau server có thể nhận diện và xác thực. -
Thời hạn cookie là 30 ngày.
Tự động đăng nhập bằng cookie
Trong mọi request, bạn cần kiểm tra xem session user_id đã tồn tại chưa. Nếu chưa có, thì kiểm tra cookie rememberme. Nếu cookie hợp lệ, bạn tự động đăng nhập.

