Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork71
Description
JWT Authentication Migration: Benefits and Technical Debt Reduction
Title
JWT Authentication Migration: Benefits and Technical Debt Reduction
Description
English Description
Context: MikoPBX has successfully migrated from traditional PHP session-based authentication to modern JWT (JSON Web Token) authentication with refresh tokens. This migration represents a significant architectural improvement and sets the foundation for future enhancements.
Current Implementation Status
✅ What has been completed:
- JWT-based authentication system (
/pbxcore/api/v3/auth:login) - Access tokens (15 min lifetime) and refresh tokens (30 days, httpOnly cookies)
- Token rotation on refresh for enhanced security
- Password and passkey (WebAuthn) authentication support
- Rate limiting and device tracking
- Redis-based token storage (fast O(1) operations)
- Automatic token cleanup
- Shared
CredentialsValidatorfor both web UI and REST API - Nginx Lua-based JWT validation for protected resources
- Backward compatibility with legacy session-based authentication
🔄 Still in transition:
SessionProviderstill registered for backward compatibility- Some legacy code paths check
session->has(SESSION_ID) - Language preferences still stored in session
- Module authentication hooks use session-based parameters
Benefits of JWT Authentication Migration
1. Scalability & Stateless Architecture
- JWT tokens are self-contained and don't require server-side session storage
- Eliminates session affinity requirements in load balancer configurations
- Enables true horizontal scaling without shared session storage
- Redis used only for refresh token revocation, not for every request validation
2. Performance Improvements
- No session I/O on every authenticated request
- Nginx can validate JWT tokens via Lua without PHP overhead
- Reduced Redis operations (only for refresh, not for access tokens)
- Lower memory footprint on PHP-FPM workers
3. Security Enhancements
- Short-lived access tokens (15 min) limit exposure window
- Refresh token rotation prevents token replay attacks
- httpOnly cookies prevent XSS token theft
- SameSite=Strict protects against CSRF
- Device tracking (IP, User-Agent) for suspicious activity detection
- Centralized token revocation via Redis
4. Multi-Tenancy Foundation
- JWT payload can include tenant ID without database lookups
- Stateless authentication essential for SaaS/multi-tenant architecture
- Easy to implement tenant isolation and resource quotas
- Simplifies billing and usage tracking per tenant
5. Technical Debt Reduction
- Eliminated code duplication between web UI and REST API authentication
- Shared
CredentialsValidatorinstead of duplicate credential checks - Cleaner separation of concerns (auth, authorization, session management)
- Modern authentication standard (RFC 7519) instead of custom session logic
- Better testability with stateless authentication
6. API-First Architecture
- RESTful authentication endpoints (
/pbxcore/api/v3/auth:*) - Same authentication flow for SPA, mobile apps, and REST clients
- Bearer token standard for API authentication
- Easier integration with third-party services and microservices
7. Future-Proofing
- Foundation for OAuth 2.0 / OpenID Connect implementation
- Compatible with JWT-based SSO (Single Sign-On)
- Enables federated authentication across multiple MikoPBX instances
- Supports modern security standards (FIDO2, WebAuthn already integrated)
Technical Debt Addressed
Before JWT Migration:
// ❌ Duplicate authentication logic in SessionController and REST API// SessionController.phpif (checkCredentials($login,$password)) {$session->set(SESSION_ID, ['role' =>'admin', ...]);}// REST API - duplicated logicif (checkCredentials($login,$password)) {// Different implementation, same logic}
After JWT Migration:
// ✅ Shared authentication through CredentialsValidator$sessionParams = CredentialsValidator::authenticate($login,$password,$security);if ($sessionParams !==null) {// Generate JWT and refresh token$accessToken = JWTHelper::generate(['userId' =>...,'role' =>...]);}
Session Storage Overhead Eliminated:
- Before: Every request → PHP session read from Redis → Session data deserialization
- After: Access token validated by Nginx Lua (no PHP, no Redis on most requests)
Remaining Cleanup Tasks
To fully complete the migration and remove remaining technical debt:
Remove SessionProvider dependency where JWT is available
AssetProvideralready migrated to check JWT cookiesLanguageProvidercan use JWT payload for user preferences- Remove
session->set(SESSION_ID, ...)calls in legacy code
Migrate language preferences to user profile/JWT
- Store language in user settings table instead of session
- Include language in JWT payload for frontend
- Remove session dependency in
LanguageProvider
Update module authentication hooks
- Standardize module authentication to return JWT-compatible data
- Update
WebUIConfigInterface::AUTHENTICATE_USERcontract - Provide migration guide for module developers
Complete Nginx integration
- Expand JWT validation to all protected endpoints
- Remove legacy session checks in Lua scripts
- Document Nginx JWT validation architecture
Audit and remove legacy session checks
- Find all
session->has(SESSION_ID)checks - Replace with JWT-based authentication checks
- Remove unnecessary backward compatibility code
- Find all
Metrics & Impact
Performance:
- Estimated 20-30% reduction in average request latency for authenticated requests
- 50% reduction in Redis operations for authentication
- Eliminated session serialization/deserialization overhead
Security:
- Reduced token exposure window from hours (session) to 15 minutes (JWT)
- Eliminated session fixation attack vector
- Improved CSRF protection with SameSite cookies
Developer Experience:
- Single authentication codebase instead of 2+ implementations
- Standard JWT libraries available in all languages
- Easier to write integration tests (stateless)
Русское описание
Контекст: MikoPBX успешно мигрировал с традиционной сессионной аутентификации PHP на современную JWT (JSON Web Token) аутентификацию с токенами обновления. Эта миграция представляет собой значительное архитектурное улучшение и закладывает фундамент для будущих расширений.
Статус текущей реализации
✅ Что уже реализовано:
- Система аутентификации на базе JWT (
/pbxcore/api/v3/auth:login) - Access токены (15 мин) и refresh токены (30 дней, httpOnly cookies)
- Ротация токенов при обновлении для повышенной безопасности
- Поддержка аутентификации по паролю и passkey (WebAuthn)
- Ограничение частоты запросов и отслеживание устройств
- Хранилище токенов на базе Redis (быстрые O(1) операции)
- Автоматическая очистка истекших токенов
- Общий
CredentialsValidatorдля веб-интерфейса и REST API - Валидация JWT через Nginx Lua для защищенных ресурсов
- Обратная совместимость с legacy сессионной аутентификацией
🔄 Все еще в переходном состоянии:
SessionProviderвсе еще зарегистрирован для обратной совместимости- Некоторые legacy участки кода проверяют
session->has(SESSION_ID) - Настройки языка все еще хранятся в сессии
- Хуки аутентификации модулей используют сессионные параметры
Преимущества миграции на JWT аутентификацию
1. Масштабируемость и stateless архитектура
- JWT токены самодостаточны и не требуют серверного хранилища сессий
- Устраняет необходимость в session affinity в конфигурации балансировщика нагрузки
- Обеспечивает истинное горизонтальное масштабирование без общего хранилища сессий
- Redis используется только для отзыва refresh токенов, а не для валидации каждого запроса
2. Улучшение производительности
- Нет операций ввода-вывода сессий при каждом аутентифицированном запросе
- Nginx может проверять JWT токены через Lua без накладных расходов PHP
- Сокращение операций Redis (только для refresh, не для access токенов)
- Меньший объем памяти на PHP-FPM воркерах
3. Улучшения безопасности
- Короткоживущие access токены (15 мин) ограничивают окно уязвимости
- Ротация refresh токенов предотвращает атаки повторного воспроизведения
- httpOnly cookies предотвращают кражу токенов через XSS
- SameSite=Strict защищает от CSRF
- Отслеживание устройств (IP, User-Agent) для обнаружения подозрительной активности
- Централизованный отзыв токенов через Redis
4. Фундамент для мультитенантности
- Payload JWT может включать ID арендатора без обращений к БД
- Stateless аутентификация критична для SaaS/мультитенантной архитектуры
- Легко реализовать изоляцию арендаторов и квоты ресурсов
- Упрощает биллинг и отслеживание использования для каждого арендатора
5. Сокращение технического долга
- Устранено дублирование кода между веб-интерфейсом и REST API аутентификацией
- Общий
CredentialsValidatorвместо дублирующихся проверок учетных данных - Более четкое разделение ответственности (аутентификация, авторизация, управление сессиями)
- Современный стандарт аутентификации (RFC 7519) вместо кастомной логики сессий
- Лучшая тестируемость с stateless аутентификацией
6. API-first архитектура
- RESTful эндпоинты аутентификации (
/pbxcore/api/v3/auth:*) - Одинаковый поток аутентификации для SPA, мобильных приложений и REST клиентов
- Стандарт Bearer token для аутентификации API
- Более простая интеграция со сторонними сервисами и микросервисами
7. Готовность к будущему
- Фундамент для реализации OAuth 2.0 / OpenID Connect
- Совместимость с SSO на базе JWT (Single Sign-On)
- Обеспечивает федеративную аутентификацию между несколькими инстансами MikoPBX
- Поддерживает современные стандарты безопасности (FIDO2, WebAuthn уже интегрирован)
Устраненный технический долг
До миграции на JWT:
// ❌ Дублирование логики аутентификации в SessionController и REST API// SessionController.phpif (checkCredentials($login,$password)) {$session->set(SESSION_ID, ['role' =>'admin', ...]);}// REST API - дублированная логикаif (checkCredentials($login,$password)) {// Другая реализация, та же логика}
После миграции на JWT:
// ✅ Общая аутентификация через CredentialsValidator$sessionParams = CredentialsValidator::authenticate($login,$password,$security);if ($sessionParams !==null) {// Генерируем JWT и refresh токен$accessToken = JWTHelper::generate(['userId' =>...,'role' =>...]);}
Устранены накладные расходы хранилища сессий:
- До: Каждый запрос → Чтение PHP сессии из Redis → Десериализация данных сессии
- После: Access токен валидируется Nginx Lua (без PHP, без Redis для большинства запросов)
Оставшиеся задачи по очистке
Для полного завершения миграции и удаления оставшегося технического долга:
Удалить зависимость от SessionProvider там, где доступен JWT
AssetProviderуже мигрирован на проверку JWT cookiesLanguageProviderможет использовать JWT payload для настроек пользователя- Удалить вызовы
session->set(SESSION_ID, ...)в legacy коде
Мигрировать настройки языка в профиль пользователя/JWT
- Хранить язык в таблице настроек пользователя вместо сессии
- Включать язык в JWT payload для фронтенда
- Удалить зависимость от сессии в
LanguageProvider
Обновить хуки аутентификации модулей
- Стандартизировать аутентификацию модулей для возврата JWT-совместимых данных
- Обновить контракт
WebUIConfigInterface::AUTHENTICATE_USER - Предоставить руководство по миграции для разработчиков модулей
Завершить интеграцию с Nginx
- Расширить валидацию JWT на все защищенные эндпоинты
- Удалить legacy проверки сессий в Lua скриптах
- Документировать архитектуру JWT валидации в Nginx
Аудит и удаление legacy проверок сессий
- Найти все проверки
session->has(SESSION_ID) - Заменить на проверки аутентификации на базе JWT
- Удалить ненужный код обратной совместимости
- Найти все проверки
Метрики и влияние
Производительность:
- Ожидаемое сокращение средней задержки запросов на 20-30% для аутентифицированных запросов
- Сокращение операций Redis на 50% для аутентификации
- Устранены накладные расходы на сериализацию/десериализацию сессий
Безопасность:
- Сокращено окно уязвимости токена с часов (сессия) до 15 минут (JWT)
- Устранен вектор атаки фиксации сессии
- Улучшена CSRF защита с SameSite cookies
Опыт разработчиков:
- Единая кодовая база аутентификации вместо 2+ реализаций
- Стандартные JWT библиотеки доступны на всех языках
- Проще писать интеграционные тесты (stateless)
Labels
- enhancement
- security
- authentication
- technical-debt
- architecture
- multi-tenancy
- api
Priority
medium
Milestone
2025.1 or Future Enhancements
Related Components
src/PBXCoreREST/Controllers/Auth/RestController.php- JWT authentication endpointssrc/Common/Library/Auth/CredentialsValidator.php- Shared authentication logicsrc/PBXCoreREST/Lib/Auth/- JWT authentication actionssrc/Common/Providers/SessionProvider.php- Legacy session provider (to be phased out)src/AdminCabinet/Providers/AssetProvider.php- JWT cookie validationsrc/Core/System/RootFS/etc/nginx/mikopbx/lua/unified-security.lua- Nginx JWT validation
References
- RFC 7519: JSON Web Token (JWT) -https://datatracker.ietf.org/doc/html/rfc7519
- RFC 6749: OAuth 2.0 Framework -https://datatracker.ietf.org/doc/html/rfc6749
- OWASP JWT Security Cheat Sheet -https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html