A JWT (JSON Web Token) is a compact, URL-safe way of securely transmitting information between a client and a server as a JSON object.
It is commonly used for authentication and authorization in modern web applications and APIs.
This implementation provides two main methods:
encode(array $payload, int $exp) → Encode and generate a token.
decode(string $jwt) / decodeFromBearer() → Decode and verify a token.
Once the user is authenticated, you can generate a token that stores your data in the $payload array.
This token can then be sent to your frontend (e.g., JavaScript) for later use.
<?php
use Krystal\Authentication\JWT;
$secret = 'my-secret'; // Your unique secret key (keep it in configuration)
$ttl = 3600; // Time-to-live in seconds
$payload = [
'sub' => '1', // User ID
// Any other custom data (e.g. role, email, permissions)
];
$jwt = new JWT($secret);
// Generate a token and send it to JavaScript
echo $jwt->create($payload, $ttl);
On subsequent requests, you can verify the token either from a query parameter or from the Authorization Bearer header.
<?php
use Krystal\Authentication\JWT;
$secret = 'my-secret';
$jwt = new JWT($secret);
// Option 1: Token from query string (?token=...)
$payload = $jwt->decode($_GET['token']);
// Option 2: Token from Authorization header (Bearer <token>)
$payload = $jwt->decodeFromBearer();
if ($payload) {
// Token is valid and not expired - proceed with request
} else {
// Invalid or expired token
}
On the frontend, you authenticate by sending login credentials to the server.
If successful, the server returns a JWT which you can store and send with each request.
// Login and receive JWT
async function login() {
const response = await fetch("/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: new URLSearchParams({ username: "alice", password: "password123" })
});
const data = await response.json();
if (data.success) {
console.log("Token received:", data.token);
// Save token (for demo purposes, use HttpOnly cookie in production)
localStorage.setItem("jwt", data.token);
// Call a protected route
getProfile();
} else {
console.error("Login failed:", data.message);
}
}
// Example protected request
async function getProfile() {
const token = localStorage.getItem("jwt");
const response = await fetch("/auth/profile", {
method: "GET",
headers: {
"Authorization": "Bearer " + token
}
});
const data = await response.json();
console.log("Profile:", data);
}
// Start login flow
login();
/auth/login.Authorization: Bearer <token>.