JSON Web Token (JWT) is a secure and widely used method for authentication and authorization in web applications. In this guide, we’ll build a basic authentication system using JWT with PHP.
1. What is JWT?
A JWT consists of three main parts:
- Header: Specifies the algorithm used.
- Payload: Contains user-specific data.
- Signature: Verifies that the token hasn’t been altered.
A JWT looks like this:
PLAINTEXT
header.payload.signature
2. Install JWT Library for PHP
We'll use the firebase/php-jwt library. Install it via Composer:
SH
composer require firebase/php-jwt
3. Securely Store the Secret Key
Use a .env file to store your secret key instead of hardcoding it. We'll use vlucas/phpdotenv for loading environment variables.
Step 1: Install dotenv
SH
composer require vlucas/phpdotenv
Step 2: Create .env File
INI
SECRET_KEY=your_secret_key
Step 3: Load the .env File in PHP
PHP
use Dotenv\Dotenv;
require 'vendor/autoload.php';
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();
$secret_key = $_ENV['SECRET_KEY'];
4. Generate JWT (generate_jwt.php)
PHP
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
require 'vendor/autoload.php';
$issued_at = time();
$expiration_time = $issued_at + (60 * 60); // 1 hour
$payload = [
'iss' => 'http://localhost',
'iat' => $issued_at,
'exp' => $expiration_time,
'user_id' => 1,
'username' => 'testuser'
];
$jwt = JWT::encode($payload, $_ENV['SECRET_KEY'], 'HS256');
echo json_encode(['token' => $jwt]);
5. Validate JWT (validate_jwt.php)
PHP
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
require 'vendor/autoload.php';
$headers = getallheaders();
if (!isset($headers['Authorization'])) {
echo json_encode(['error' => 'Token not found']);
exit;
}
$token = str_replace('Bearer ', '', $headers['Authorization']);
try {
$decoded = JWT::decode($token, new Key($_ENV['SECRET_KEY'], 'HS256'));
echo json_encode(['message' => 'Token is valid', 'data' => $decoded]);
} catch (Exception $e) {
echo json_encode(['error' => 'Invalid token']);
}
6. Authenticate via JWT on Login (login.php)
PHP
session_start();
include_once 'database.php';
use Firebase\JWT\JWT;
$database = new Database();
$db = $database->getConnection();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'];
$password = $_POST['password'];
$query = 'SELECT id, username, password FROM users WHERE email = :email';
$stmt = $db->prepare($query);
$stmt->bindParam(':email', $email);
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user && password_verify($password, $user['password'])) {
$issued_at = time();
$expiration_time = $issued_at + (60 * 60);
$payload = [
'iss' => 'http://localhost',
'iat' => $issued_at,
'exp' => $expiration_time,
'user_id' => $user['id'],
'username' => $user['username']
];
$jwt = JWT::encode($payload, $_ENV['SECRET_KEY'], 'HS256');
echo json_encode(['token' => $jwt]);
} else {
echo json_encode(['error' => 'Invalid email or password']);
}
}
7. Security Tips
- Secure your secret key: Store it in a
.envfile instead of hardcoding it. - Set token expiration: Limit token lifetime to reduce risk.
- Use HTTPS: Always transmit tokens over encrypted connections.
JWT provides a secure and flexible way to handle authentication in PHP applications. With dotenv, you can securely manage environment variables such as secret keys.
Related Articles
Comments ()
No comments yet. Be the first to comment!