OAuth2 — IO7 Framework
Внимание
Данная статья документации написана нейросетью. Возможны некоторые расхождения и неточность информации!
Обзор
IO7 предоставляет реализацию OAuth2 сервера и клиента для построения SSO-систем. Сервер обрабатывает authorization code flow, обмен токенами, обновление и отзыв. Клиент подключается к OAuth2 серверу для авторизации приложений.
IO\Auth\OAuth2Server
OAuth2 сервер для SSO проекта. Обрабатывает authorization code flow, token exchange, token refresh, token revocation. Реализован как singleton.
Инициализация
$server = \IO\Auth\OAuth2Server::init([
'issuer' => 'io7-sso',
'token_manager' => [
'secret_key' => 'my-secret-key',
'access_ttl' => 3600,
'refresh_ttl' => 2592000,
],
'auth_code_ttl' => 600,
]);
Конфигурация
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
issuer | string | 'io7-sso' | Нет | Издатель токенов |
token_manager | array | — | Да | Конфигурация TokenManager |
auth_code_ttl | int | 600 | Нет | Время жизни auth code в секундах (10 мин) |
Методы
init(array $config): self
Инициализация OAuth2 сервера.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$config | array | — | Да | Конфигурация сервера |
| Возврат | self | Экземпляр OAuth2Server |
getInstance(): self
Получение единственного экземпляра (singleton).
registerClient(string $clientId, string $clientSecret, array $redirectURIs): void
Регистрация OAuth2 клиента.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$clientId | string | — | Да | Идентификатор клиента |
$clientSecret | string | — | Да | Секрет клиента |
$redirectURIs | array | — | Да | Разрешённые URI для перенаправления |
$server->registerClient(
'client-abc',
'client-secret',
['https://example.com/callback', 'https://app.example.com/callback']
);
getAuthorizationUrl(string $clientId, string $redirectUri, array $scopes = [], string $state = ''): string
Получение URL для авторизации.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$clientId | string | — | Да | Идентификатор клиента |
$redirectUri | string | — | Да | URI для перенаправления |
$scopes | array | [] | Нет | Запрашиваемые скоупы |
$state | string | '' | Нет | Случайная строка для CSRF-защиты |
| Возврат | string | URL для перенаправления |
$authUrl = $server->getAuthorizationUrl(
'client-abc',
'https://example.com/callback',
['read', 'write'],
'random-state-string'
);
header('Location: ' . $authUrl);
createAuthCode(string $userId, string $clientId, array $scopes, string $redirectUri): string
Создание authorization code.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$userId | string | — | Да | Идентификатор пользователя |
$clientId | string | — | Да | Идентификатор клиента |
$scopes | array | — | Да | Скоупы доступа |
$redirectUri | string | — | Да | URI для перенаправления |
| Возврат | string | Authorization code |
$code = $server->createAuthCode(
'user-123',
'client-abc',
['read', 'write'],
'https://example.com/callback'
);
exchangeCode(string $code, string $clientId, string $clientSecret): array
Обмен authorization code на токены.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$code | string | — | Да | Authorization code |
$clientId | string | — | Да | Идентификатор клиента |
$clientSecret | string | — | Да | Секрет клиента |
| Возврат | array | ['access_token', 'refresh_token', 'expires_in', 'token_type'] | ||
| Исключение | \InvalidArgumentException | Если код невалиден или клиент не найден |
$tokens = $server->exchangeCode('auth-code-123', 'client-abc', 'client-secret');
$accessToken = $tokens['access_token'];
refreshToken(string $refreshToken, string $clientId, string $clientSecret): array
Обновление токенов с помощью refresh token.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$refreshToken | string | — | Да | Refresh token |
$clientId | string | — | Да | Идентификатор клиента |
$clientSecret | string | — | Да | Секрет клиента |
| Возврат | array | ['access_token', 'refresh_token', 'expires_in', 'token_type'] | ||
| Исключение | \InvalidArgumentException | Если refresh token невалиден |
$tokens = $server->refreshToken('refresh-token-123', 'client-abc', 'client-secret');
validateToken(string $token): ?array
Валидация access token.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$token | string | — | Да | Access token |
| Возврат | array|null | Payload токена или null |
$payload = $server->validateToken($accessToken);
if ($payload !== null) {
$userId = $payload['sub'];
$scopes = $payload['scopes'];
}
revokeToken(string $token): bool
Отзыв токена.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$token | string | — | Да | Access или refresh token |
| Возврат | bool | Всегда true (заглушка) |
getIssuer(): string
Получение issuer сервера.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
| Возврат | string | Issuer |
IO\Auth\OAuth2Client
OAuth2 клиент для приложений, которые авторизуются через OAuth2 сервер (SSO).
Конструктор
$client = new \IO\Auth\OAuth2Client(
'client-id',
'client-secret',
'https://sso.example.com/authorize',
'https://sso.example.com/token',
'https://sso.example.com/userinfo'
);
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$clientId | string | — | Да | Идентификатор клиента |
$clientSecret | string | — | Да | Секрет клиента |
$authUrl | string | — | Да | URL авторизации |
$tokenUrl | string | — | Да | URL получения токена |
$userInfoUrl | string | — | Нет | URL получения информации о пользователе (опционально) |
Методы
getAuthorizationUrl(string $redirectUri, array $scopes = []): string
Получить URL для редиректа на авторизацию.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$redirectUri | string | — | Да | URI для回调а |
$scopes | array | [] | Нет | Запрашиваемые скоупы |
| Возврат | string | URL для авторизации |
$url = $client->getAuthorizationUrl('https://example.com/callback', ['openid', 'profile']);
header('Location: ' . $url);
exchangeCode(string $code, string $redirectUri): array
Обмен code на токен.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$code | string | — | Да | Authorization code |
$redirectUri | string | — | Да | URI для callbackа |
| Возврат | array | ['access_token', 'refresh_token', 'expires_in'] | ||
| Исключение | \RuntimeException | При ошибке запроса |
$token = $client->exchangeCode('auth_code', 'https://example.com/callback');
refreshToken(string $refreshToken): array
Обновление токена.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$refreshToken | string | — | Да | Refresh token |
| Возврат | array | Новые токены | ||
| Исключение | \RuntimeException | При ошибке запроса |
$newToken = $client->refreshToken('refresh_token_value');
getUserInfo(string $accessToken): ?array
Получить информацию о пользователе.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$accessToken | string | — | Да | Access token |
| Возврат | array|null | Информация о пользователе |
$userInfo = $client->getUserInfo('access_token_value');
revokeToken(string $token): bool
Отзыв токена.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$token | string | — | Да | Токен для отзыва |
| Возврат | bool | Успешность отзыва |
$revoked = $client->revokeToken('token_to_revoke');
getStoredToken(): ?array
Получить сохранённый токен из памяти.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
| Возврат | array|null | Токен или null |
storeToken(array $token): void
Сохранить токен в память.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
$token | array | — | Да | Токен для сохранения |
clearToken(): void
Очистить токен.
isAuthenticated(): bool
Проверить, авторизован ли пользователь.
| Параметр | Тип | Значение по умолчанию | Обязателен | Описание |
|---|---|---|---|---|
| Возврат | bool | true если авторизован |
if ($client->isAuthenticated()) {
// Пользователь авторизован
}
Пример полного цикла (клиент)
// 1. Создание клиента
$client = new \IO\Auth\OAuth2Client(
getenv('OAUTH2_CLIENT_ID'),
getenv('OAUTH2_CLIENT_SECRET'),
'https://sso.example.com/authorize',
'https://sso.example.com/token',
'https://sso.example.com/userinfo'
);
// 2. Получение URL для авторизации
$url = $client->getAuthorizationUrl(
'https://myapp.example.com/callback',
['openid', 'profile', 'email']
);
header('Location: ' . $url);
// 3. Обработка callback (после редиректа)
$code = $_GET['code'];
$token = $client->exchangeCode($code, 'https://myapp.example.com/callback');
$client->storeToken($token);
// 4. Получение информации о пользователе
$user = $client->getUserInfo($token['access_token']);
// 5. Обновление токена
$newToken = $client->refreshToken($token['refresh_token']);
Пример сервера
// Инициализация сервера
$server = \IO\Auth\OAuth2Server::init([
'issuer' => 'io7-sso',
'token_manager' => [
'secret_key' => getenv('JWT_SECRET'),
],
]);
// Регистрация клиента
$server->registerClient('my-app', 'app-secret', ['https://myapp.example.com/callback']);
// Получение URL авторизации
$authUrl = $server->getAuthorizationUrl('my-app', 'https://myapp.example.com/callback', ['read']);
// Обмен кода на токены (после авторизации пользователя)
$tokens = $server->exchangeCode($code, 'my-app', 'app-secret');
// Обновление токена
$newTokens = $server->refreshToken($refreshToken, 'my-app', 'app-secret');
// Валидация токена
$payload = $server->validateToken($accessToken);