JWT hoặc session-based authentication
Sau khi đã hiểu cơ chế đăng nhập cơ bản, bài học này giúp bạn triển khai xác thực thực tế bằng JWT (dùng cho REST API) hoặc Session (dùng cho ứng dụng truyền thống). Bạn sẽ học cách mã hóa, giải mã JWT và lưu thông tin đăng nhập để tái sử dụng trong ứng dụng.
Mục tiêu
- Áp dụng JWT để xác thực trong RESTful API.
- Quản lý đăng nhập bằng session.
- Phân biệt giữa session-based và token-based authentication.

1 JWT Authentication (API)
a. Cài thư viện JWT:
composer require firebase/php-jwt
b. Tạo JWT khi đăng nhập:
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
$secretKey = "your_secret_key";
$app->post('/api/login', function ($request, $response) use ($secretKey) {
$data = $request->getParsedBody();
$username = $data['username'];
$password = $data['password'];
if ($username === 'admin' && $password === '123456') {
$payload = [
'iss' => 'slim-api',
'sub' => $username,
'iat' => time(),
'exp' => time() + 3600
];
$jwt = JWT::encode($payload, $secretKey, 'HS256');
return $response->withJson(['token' => $jwt]);
}
return $response->withJson(['error' => 'Unauthorized'], 401);
});
c. Middleware xác thực JWT:
$jwtMiddleware = function ($request, $handler) use ($secretKey) {
$authHeader = $request->getHeaderLine('Authorization');
if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
$jwt = $matches[1];
try {
$decoded = JWT::decode($jwt, new Key($secretKey, 'HS256'));
$request = $request->withAttribute('user', $decoded->sub);
return $handler->handle($request);
} catch (Exception $e) {
return (new Slim\Psr7\Response())->withStatus(401)->withHeader('Content-Type', 'application/json')
->getBody()->write(json_encode(['error' => 'Invalid token']));
}
}
return (new Slim\Psr7\Response())->withStatus(401)->withHeader('Content-Type', 'application/json')
->getBody()->write(json_encode(['error' => 'Token not provided']));
};
d. Sử dụng middleware:
$app->get('/api/profile', function ($request, $response) {
$user = $request->getAttribute('user');
return $response->withJson(['username' => $user]);
})->add($jwtMiddleware);
2 Session-based Authentication (Truyền thống)
a. Lưu session khi login:
session_start();
$app->post('/login', function ($request, $response) {
$data = $request->getParsedBody();
if ($data['username'] === 'admin' && $data['password'] === '123456') {
$_SESSION['user'] = $data['username'];
return $response->withRedirect('/dashboard');
}
return $response->write('Sai tài khoản hoặc mật khẩu');
});
b. Middleware kiểm tra đăng nhập:
$authMiddleware = function ($request, $handler) {
if (!isset($_SESSION['user'])) {
return (new Slim\Psr7\Response())->withStatus(302)->withHeader('Location', '/login');
}
return $handler->handle($request);
};
$app->get('/dashboard', function ($request, $response) {
return $response->write("Chào mừng, " . $_SESSION['user']);
})->add($authMiddleware);
Kết luận
- JWT phù hợp với các API RESTful không trạng thái.
- Session đơn giản hơn, phù hợp với ứng dụng truyền thống có giao diện HTML.
- Middleware là công cụ cốt lõi để bảo vệ các route yêu cầu xác thực.
Bài tập thực hành
-
Cài đặt thư viện JWT:
- Dùng
composer require firebase/php-jwt
.
- Dùng
-
Tạo route login trả JWT:
- Nếu đăng nhập đúng, trả
token
chứausername
vàexp
.
- Nếu đăng nhập đúng, trả
-
Tạo middleware xác thực JWT:
- Nếu token hợp lệ, cho phép truy cập route
/api/profile
.
- Nếu token hợp lệ, cho phép truy cập route
-
Session login:
- Tạo form login truyền thống lưu
$_SESSION['user']
. - Bảo vệ route
/dashboard
bằng session middleware.
- Tạo form login truyền thống lưu

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.
Xem thêm

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.
Liên hệ công việc qua email dưới đây.
lhvuctu@gmail.com