1. Tổng quan chức năng
Mini project này minh họa cách sử dụng cookie để xác minh người dùng đã đăng nhập.
Các chức năng chính gồm:
-
Đăng ký tài khoản (register.php)
-
Đăng nhập hệ thống (login.php)
-
Hiển thị danh sách người dùng (users.php)
-
Đăng xuất tài khoản (logout.php)
-
Quản lý cookie & token bảo mật (utility.php)
2. Cấu trúc dự án
project/
│
├── db/
│ ├── config.php
│ └── dbhelper.php
│
├── utils/
│ └── utility.php
│
├── register.php
├── login.php
├── users.php
├── logout.php
│
├── form-register.php
├── form-login.php
│
├── test-cookie.php
├── list-cookie.php
├── delete-cookie.php
└── readme.txt
3. Cấu trúc CSDL (MySQL)
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
fullname VARCHAR(50) NOT NULL,
email VARCHAR(150),
birthday DATE,
password VARCHAR(32),
address VARCHAR(200),
token VARCHAR(32)
);
👉 Bảng users lưu thông tin người dùng, gồm cả token – chính là giá trị cookie giúp xác định người đăng nhập.
4. Giải thích chi tiết từng file
🧩 config.php
define('HOST', 'localhost');
define('USERNAME', 'root');
define('PASSWORD', '');
define('DATABASE', 'C2010L');
define('MD5_PRIVATE_KEY', '09JJJjhh7834jHJG876312^&%shjdgsjagdasKoks');
-
File này chứa thông tin kết nối database.
-
MD5_PRIVATE_KEYlà chuỗi bí mật, dùng để mã hóa mật khẩu và token.
🧩 dbhelper.php
function execute($sql) {
$conn = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE);
mysqli_set_charset($conn, 'utf8');
mysqli_query($conn, $sql);
mysqli_close($conn);
}
-
Dùng để thực thi câu lệnh SQL dạng
INSERT,UPDATE,DELETE.
function executeResult($sql) {
$conn = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE);
mysqli_set_charset($conn, 'utf8');
$resultset = mysqli_query($conn, $sql);
$data = [];
while (($row = mysqli_fetch_array($resultset, 1)) != null) {
$data[] = $row;
}
mysqli_close($conn);
return $data;
}
-
Dùng để lấy dữ liệu SELECT và trả về mảng
$data.
🧩 utility.php
Đây là thư viện tiện ích quan trọng nhất, giúp mã hóa, lọc input, và xác thực token.
function getPwdSecurity($pwd) {
return md5(md5($pwd).MD5_PRIVATE_KEY);
}
-
Mã hóa mật khẩu bằng MD5 hai lớp + khóa bí mật riêng → bảo mật hơn.
function validateToken() {
$token = '';
if (isset($_COOKIE['token'])) {
$token = $_COOKIE['token'];
$sql = "select * from users where token = '$token'";
$data = executeResult($sql);
if ($data != null && count($data) > 0) {
return $data[0];
}
}
return null;
}
-
Khi người dùng truy cập bất kỳ trang nào, hàm này đọc cookie
token, tìm trong DB:-
Nếu token hợp lệ → trả về thông tin user.
-
Nếu không → trả về
null.
-
→ Đây là trung tâm của cơ chế ghi nhớ đăng nhập tự động bằng cookie.
Các hàm hỗ trợ GET, POST và tránh SQL Injection
function getGET($key) {...}
function getPOST($key) {...}
function fixSqlInjection($str) {...}
-
Dùng để lấy dữ liệu từ form an toàn hơn.
-
Hàm
fixSqlInjection()sẽ escape ký tự đặc biệt để chống tấn công SQL injection.
🧩 register.php
-
Trang đăng ký tài khoản mới.
Luồng hoạt động:
-
Gọi
validateToken()→ nếu người dùng đã login thì chuyển hướng đếnusers.php. -
Nếu chưa đăng nhập, nạp form đăng ký từ
form-register.php.
form-register.php
if (!empty($_POST)) {
$fullname = getPOST('fullname');
$password = getPOST('password');
$email = getPOST('email');
$birthday = getPOST('birthday');
$address = getPOST('address');
if ($fullname != '' && $password != '' && $email != '') {
$password = getPwdSecurity($password);
$sql = "insert into users (fullname, password, email, birthday, address)
values ('$fullname', '$password', '$email', '$birthday', '$address')";
execute($sql);
header('Location: login.php');
die();
}
}
✅ Khi người dùng submit form:
-
Dữ liệu được kiểm tra và mã hóa mật khẩu.
-
Thêm vào DB.
-
Tự động chuyển đến trang
login.php.
🧩 login.php
-
Nếu người dùng đã login → chuyển ngay đến
users.php. -
Nếu chưa login → hiển thị form đăng nhập (
form-login.php).
form-login.php
if (!empty($_POST)) {
$password = getPOST('password');
$email = getPOST('email');
if ($password != '' && $email != '') {
$password = getPwdSecurity($password);
$sql = "select * from users where email = '$email' and password = '$password'";
$data = executeResult($sql);
if ($data != null && count($data) > 0) {
$token = getPwdSecurity(time().$data[0]['email']);
setcookie('token', $token, time()+7*24*60*60, '/');
$sql = "update users set token = '$token' where id = " .$data[0]['id'];
execute($sql);
header('Location: users.php');
die();
}
}
}
✅ Khi đăng nhập thành công:
-
Tạo token duy nhất từ
time()+ email → mã hóa MD5. -
Lưu token vào cookie và database.
-
Khi người dùng mở lại web, hệ thống chỉ cần so sánh token này để xác thực tự động.
🧩 users.php
$user = validateToken();
if ($user == null) {
header('Location: login.php');
die();
}
✅ Khi truy cập trang users.php:
-
Nếu cookie
tokenhợp lệ → cho phép vào trang. -
Nếu không hợp lệ → tự động chuyển về
login.php.
Trang này hiển thị danh sách người dùng bằng bảng HTML.
$sql = "select * from users";
$userList = executeResult($sql);
-
Kết quả hiển thị kèm tên người đăng nhập hiện tại:
<h2>Users Page - <?=$user['fullname']?> (<a href="logout.php">logout</a>)</h2>
🧩 logout.php
if (isset($_COOKIE['token'])) {
require_once ('../db/dbhelper.php');
require_once ('../utils/utility.php');
$token = $_COOKIE['token'];
$sql = "update users set token = null where token = '$token'";
execute($sql);
}
setcookie('token', '', time()-7*24*60*60, '/');
header('Location: login.php');
✅ Khi logout:
-
Xóa token trong DB (đảm bảo không thể reuse token cũ).
-
Xóa cookie khỏi trình duyệt.
-
Chuyển hướng lại
login.php.
🧩 test-cookie.php, list-cookie.php, delete-cookie.php
Các file này dùng để thực hành cookie:
-
test-cookie.php: tạo cookie -
list-cookie.php: đọc và in toàn bộ cookie -
delete-cookie.php: xóa cookie bằng cách đặt thời gian hết hạn trong quá khứ
5. Quy trình hoạt động tổng thể
-
Người dùng đăng ký → lưu DB.
-
Người dùng đăng nhập:
-
Nếu đúng email & mật khẩu → sinh token mới → lưu DB + cookie.
-
-
Khi mở lại web hoặc vào
users.php:-
Hệ thống gọi
validateToken()→ xác thực cookie token.
-
-
Đăng xuất:
-
Xóa token trong DB + xóa cookie.
-
→ Đây là mô hình login persistent (ghi nhớ đăng nhập) thực tế mà nhiều website áp dụng.
6. Điểm hay & Bảo mật
✅ Ưu điểm:
-
Sử dụng cookie để ghi nhớ người dùng sau khi tắt trình duyệt.
-
Token thay đổi mỗi lần đăng nhập → không thể bị reuse.
-
Không lưu mật khẩu thô → đã mã hóa MD5 với khóa riêng.
⚠️ Lưu ý bảo mật:
-
Nên dùng
password_hash()thay vì MD5 trong thực tế. -
Cookie nên có flag
HttpOnlyvàSecurenếu chạy HTTPS. -
Cần sanitize input kỹ hơn (có thể dùng prepared statement).
7. Kết luận
Bộ code này là một bài học thực tế hoàn hảo về:
-
Cách tạo, lưu, đọc và xóa cookie trong PHP.
-
Cách sử dụng token để xác thực đăng nhập thay cho session.
-
Cách xây dựng hệ thống login/logout cơ bản nhưng chuẩn quy trình.
Nếu bạn đang học PHP căn bản, hãy:
-
Chạy thử toàn bộ flow này.
-
Quan sát cookie bằng DevTools → Application → Cookies.
-
Sau đó thử cải tiến thêm tính năng: đổi mật khẩu, tự động hết hạn token, hoặc dùng JWT.
Bạn có muốn tôi vẽ sơ đồ luồng hoạt động (flow diagram) minh họa cách cookie/token hoạt động trong hệ thống này không?
(VD: từ login → lưu token → validate → logout) — nó giúp hình dung toàn bộ hệ thống trực quan hơn.
