JWT with PHP
Generate JWT tokens in PHP to connect your application users to LILA’s AI chatbot. For Laravel-specific integration with middleware and services, see the Laravel Guide.
Prerequisites
- PHP 8.1+ (8.2+ recommended)
- Composer
Installation
composer require firebase/php-jwt
Basic JWT Generation
Create a JWT token for LILA with this function:
<?php
require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;
function generateLilaToken($userId, $userEmail, $userName) {
$jwtSecret = $_ENV['LILA_JWT_SECRET'];
$payload = [
'user_id' => (string) $userId, // Must be string
'email' => $userEmail,
'name' => $userName,
'iat' => time(),
'exp' => time() + (60 * 60 * 2), // 2 hours
];
return JWT::encode($payload, $jwtSecret, 'HS256');
}
// Usage
$token = generateLilaToken(12345, 'user@example.com', 'John Doe');
Token Validation
<?php
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
function validateLilaToken($token) {
$jwtSecret = $_ENV['LILA_JWT_SECRET'];
try {
return JWT::decode($token, new Key($jwtSecret, 'HS256'));
} catch (Firebase\JWT\ExpiredException $e) {
return ['error' => 'Token expired'];
} catch (Firebase\JWT\SignatureInvalidException $e) {
return ['error' => 'Invalid signature'];
} catch (Exception $e) {
return ['error' => $e->getMessage()];
}
}
// Usage
$decoded = validateLilaToken($token);
if (!isset($decoded['error'])) {
echo "Valid token for user: " . $decoded->user_id;
}
Token Refresh Endpoint
<?php
require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;
// Load environment variables
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
// Check authentication
session_start();
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['error' => 'Authentication required']);
exit;
}
// Token refresh endpoint
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['REQUEST_URI'] === '/api/lila/refresh-token') {
$user = getUserById($_SESSION['user_id']); // Your user fetch function
$payload = [
'user_id' => (string) $user->id,
'email' => $user->email,
'name' => $user->name,
'iat' => time(),
'exp' => time() + (60 * 60 * 2),
];
$token = JWT::encode($payload, $_ENV['LILA_JWT_SECRET'], 'HS256');
header('Content-Type: application/json');
echo json_encode([
'token' => $token,
'expires_in' => 7200,
]);
exit;
}
HTML Integration
<!DOCTYPE html>
<html>
<head>
<script type="module" src="https://embed.getlila.one/loader.js"></script>
</head>
<body>
<?php if (isset($_SESSION['user_id'])): ?>
<?php $token = generateLilaToken($_SESSION['user_id'], $userEmail, $userName); ?>
<lila-widget
api-key="<?php echo $_ENV['LILA_API_KEY']; ?>"
jwt-token="<?php echo $token; ?>">
</lila-widget>
<?php endif; ?>
</body>
</html>
Production Checklist
- JWT secret stored in environment variables
- Secret is 32+ characters, randomly generated
- Token expiration set to 1-2 hours
- HTTPS enabled in production
- User ID cast to string in JWT payload
Troubleshooting
Common PHP JWT issues and solutions:
“Invalid signature” Error
Cause: JWT secret doesn’t match Dashboard
Solution:
- Copy secret from Dashboard → Settings → Setup & Integration
- Update
LILA_JWT_SECRETin your environment
”user_id claim missing” Error
Cause: User ID not in JWT payload
Solution: Ensure payload includes user_id as string:
'user_id' => (string) $user->id, // NOT just $user->id
Token Expires Immediately
Cause: Server time incorrect or exp calculation wrong
Solution:
// Correct (seconds since epoch)
'exp' => time() + (60 * 60 * 2)
// WRONG
'exp' => new DateTime('+2 hours') // Returns object, not timestamp
“Class ‘JWT’ not found”
Cause: firebase/php-jwt not installed
Solution:
composer require firebase/php-jwt
composer dump-autoload
Next Steps
- Laravel Integration - Laravel-specific setup
- JavaScript/Node.js JWT - Node examples
- Authentication Overview - Understanding JWT flow