Trong bài này, bạn sẽ thực hành viết một hệ thống đăng ký – đăng nhập cơ bản dưới dạng REST API sử dụng PHP và MySQL. Qua đó, bạn sẽ:
- Ôn lại kiến thức SQL (INSERT, SELECT, WHERE…)
- Áp dụng kỹ thuật bảo mật như hash password và SQL Injection prevention
- Biết cách tổ chức API chuẩn RESTful
Tổng quan hệ thống
Chúng ta sẽ xây dựng một hệ thống backend đơn giản với 2 chức năng:
POST /register
: Đăng ký người dùng mớiPOST /login
: Đăng nhập và trả về thông tin user nếu đúng mật khẩu
Cấu trúc thư mục:
mini-auth-api/
├── config.php
├── db.php
├── register.php
├── login.php
└── users.sql
Thiết kế cơ sở dữ liệu
Tạo bảng users
đơn giản trong MySQL:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Lưu ý:
password
sẽ lưu bản hash (không lưu plain text)username
vàemail
đều phải là duy nhất (unique)
File cấu hình và kết nối DB
config.php
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'auth_demo');
define('DB_USER', 'root');
define('DB_PASS', '');
db.php
<?php
require_once 'config.php';
try {
$pdo = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Lỗi kết nối DB: " . $e->getMessage());
}
Tạo API /register
register.php
<?php
require_once 'db.php';
$data = json_decode(file_get_contents("php://input"), true);
$username = $data['username'] ?? '';
$email = $data['email'] ?? '';
$password = $data['password'] ?? '';
if (!$username || !$email || !$password) {
http_response_code(400);
echo json_encode(['error' => 'Vui lòng nhập đầy đủ thông tin']);
exit;
}
// Băm mật khẩu
$hashedPassword = password_hash($password, PASSWORD_BCRYPT);
try {
$stmt = $pdo->prepare("INSERT INTO users (username, email, password) VALUES (?, ?, ?)");
$stmt->execute([$username, $email, $hashedPassword]);
echo json_encode(['message' => 'Đăng ký thành công']);
} catch (PDOException $e) {
http_response_code(400);
echo json_encode(['error' => 'Username hoặc Email đã tồn tại']);
}
Tạo API /login
login.php
<?php
require_once 'db.php';
$data = json_decode(file_get_contents("php://input"), true);
$username = $data['username'] ?? '';
$password = $data['password'] ?? '';
if (!$username || !$password) {
http_response_code(400);
echo json_encode(['error' => 'Thiếu username hoặc password']);
exit;
}
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
echo json_encode([
'message' => 'Đăng nhập thành công',
'user' => [
'id' => $user['id'],
'username' => $user['username'],
'email' => $user['email']
]
]);
} else {
http_response_code(401);
echo json_encode(['error' => 'Thông tin đăng nhập sai']);
}
Kiểm thử API
Bạn có thể dùng Postman, Insomnia hoặc curl để thử nghiệm:
Đăng ký:
POST http://localhost/mini-auth-api/register.php
Content-Type: application/json
{
"username": "john",
"email": "john@example.com",
"password": "secret123"
}
Đăng nhập:
POST http://localhost/mini-auth-api/login.php
Content-Type: application/json
{
"username": "john",
"password": "secret123"
}
Bảo mật và nâng cấp
- Không bao giờ lưu mật khẩu dưới dạng plain text.
- Dùng prepared statements để chống SQL Injection.
- Có thể nâng cấp thêm phần tạo JWT Token, hoặc hệ thống phân quyền theo role.
Tổng kết
Bạn vừa hoàn thành một Mini Auth API dùng PHP + SQL. Mặc dù đơn giản, nhưng đủ để làm nền tảng cho mọi ứng dụng web sau này. Hãy thử nâng cấp:
- Thêm chức năng đổi mật khẩu
- Tạo token đăng nhập
- Thêm bảng
roles
và phân quyền
Thảo luận