JWT авторизация — IO7 Framework
Внимание
Данная статья документации написана нейросетью. Возможны некоторые расхождения и неточность информации!
Обзор
IO7 использует IO\Auth\TokenManager — единый менеджер токенов, поддерживающий:
- HS256 (HMAC) — для OAuth2/стандартных JWT
- RS256 (RSA) — для совместимости с IO v6 (алгоритм JWTToken)
Библиотека: firebase/php-jwt ^6.11
TokenManager
Инициализация
// HMAC (HS256) — для OAuth2
$manager = \IO\Auth\TokenManager::init([
'secret_key' => 'my_secret_key',
'access_ttl' => 3600,
'refresh_ttl' => 2592000,
]);
// RSA (RS256) — совместимость с IO v6
$manager = \IO\Auth\TokenManager::init([
'public_key' => file_get_contents('public.pem'),
'private_key' => file_get_contents('private.pem'),
'access_ttl' => 3600,
]);
Методы HS256 (HMAC)
createAccessToken(string $userId, array $scopes = [], int $ttl = 0): string
Создать access token.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$userId | string | — | Да | ID пользователя |
$scopes | array | [] | Нет | Области доступа |
$ttl | int | 0 | Нет | Время жизни (0 = по умолчанию) |
| Возврат | string | JWT token |
$token = $manager->createAccessToken('user_123', ['read', 'write']);
createRefreshToken(string $userId, int $ttl = 0): string
Создать refresh token.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$userId | string | — | Да | ID пользователя |
$ttl | int | 0 | Нет | Время жизни (0 = 30 дней) |
| Возврат | string | JWT token |
$refreshToken = $manager->createRefreshToken('user_123');
validateAccessToken(string $token): ?array
Валидация access token.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$token | string | — | Да | JWT token |
| Возврат | array|null | Payload или null |
$payload = $manager->validateAccessToken($token);
if ($payload) {
echo $payload['sub']; // user_id
}
validateRefreshToken(string $token): ?array
Валидация refresh token.
refreshAccessToken(string $refreshToken): ?array
Обновить access token через refresh token.
$newToken = $manager->refreshAccessToken($refreshToken);
// ['access_token' => '...', 'sub' => 'user_123']
Методы RS256 (RSA, совместимость с IO v6)
encode(string $privateKey): string
Кодировать RSA токен (RS256).
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$privateKey | string | — | Да | PEM-ключ RSA приватный |
| Возврат | string | JWT token |
$manager = new TokenManager();
$manager->setUserData([
'id' => 123,
'login' => 'john_doe',
'sname' => 'Doe',
'fname' => 'John',
'pol' => 1,
]);
$jwt = $manager->encode(file_get_contents('private.pem'));
decode(string $str, string $publicKey): bool
Декодировать RSA токен.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$str | string | — | Да | JWT строка |
$publicKey | string | — | Да | PEM-ключ RSA публичный |
| Возврат | bool | true если успешно |
$manager = new TokenManager();
$valid = $manager->decode($jwtString, file_get_contents('public.pem'));
if ($valid) {
$data = $manager->getUserData();
echo $data['login'];
}
parseRSA(string $str, string $publicKey): ?self
Распарсить и провалидировать RSA токен.
$manager = TokenManager::parseRSA($jwtString, file_get_contents('public.pem'));
if ($manager) {
echo $manager->getUserData()['login'];
}
setUserData(array $user_data): void
Установить данные пользователя.
getUserData(): array
Получить данные пользователя.
equal(?self $tokenManager): bool
Сравнить два токена.
Session
Свойства
| Свойство | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$jwt_token | TokenManager|null | null | Нет | Текущий JWT токен |
$session_data | array|null | null | Нет | Данные сессии |
$current_account | int | 0 | Нет | Текущий аккаунт |
Методы
isAuth(): bool
Проверить авторизацию.
if ($session->isAuth()) {
echo $session->getUserLogin();
}
update_jwt_token(string $jwt_string): void
Обновить JWT токен из строки.
$session->update_jwt_token($jwtString);
getUserLogin(): ?string
Получить логин пользователя.
getUserID(): ?int
Получить ID пользователя.
User (пример класса)
Авторизация
// Логин
$response = \IO\Core::call('com.sso.class.user.login', [
'login' => $login,
'password' => $password,
]);
if ($response['error_code'] == EIO_OK) {
$jwt = $response['jwt_string'];
$session->update_jwt_token($jwt);
}
Создание JWT
$manager = new \IO\Auth\TokenManager();
$manager->setUserData([
'id' => $user['pkid'],
'login' => $user['login'],
'sname' => $user['sname'],
'fname' => $user['fname'],
'lname' => $user['lname'],
'pol' => $user['pol'],
]);
$jwt = $manager->encode(JWT_PRIVATE_KEY);
Парсинг JWT
$manager = \IO\Auth\TokenManager::parseRSA($jwtString, JWT_PUBLIC_KEY);
if ($manager) {
$data = $manager->getUserData();
// $data['id'], $data['login'], $data['avatar']
}
Совместимость с IO v6
Для проектов IO v6 (PHP 5.6) используется Legacy/JWTToken.php:
// В IO v6 проекте
require_once 'modules/io7/php/Legacy/JWTToken.php';
$token = new JWTToken();
$token->setUserData(['id' => 1, 'login' => 'user', ...]);
$jwt = $token->encode(file_get_contents('private.pem'));
Алгоритм RS256 совместим между IO v6 и IO v7.
JWT cookies
JWT cookies устанавливаются с параметрами безопасности по умолчанию:
- SameSite:
Lax - Secure:
true - HttpOnly:
true
Это гарантирует, что cookie не отправляется с cross-site запросов, передаётся только по HTTPS, и недоступна через JavaScript.
Функция iosetcookie() также использует SameSite=Lax по умолчанию (ранее — None).
Конфигурация
Константы
| Константа | Описание |
|---|---|
JWT_PRIVATE_KEY | Путь к RSA приватному ключу или PEM строка |
JWT_PUBLIC_KEY | Путь к RSA публичному ключу или PEM строка |
JWT_COOKIE | Имя cookie для JWT токена |
JWT_LOGIN_SALSA | Соль для хеша логина |
Генерация ключей
# Генерация RSA ключей
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem