Архитектура модуля passport/auth
Документ описывает слои модуля, порт интеграции с Passport и ключевые классы.
1. Слои
graph TD
AC[AuthController] -->|InitiateSsoLoginHandler / HandleSsoCallbackHandler| APP[application]
APP -->|PassportAuthPort| HTTP[PassportHttpClient]
APP -->|SyncUserHandler| CORE[core]
MW[PassportAuthMiddleware] -->|PassportAuthPort| HTTP
MW -->|создаёт| ID[YiiIdentity (ядро)]
AC -->|куки| BR[Браузер]
HTTP -->|HTTP| PASS[Passport API]
- presentation:
AuthController(login/callback/logout),PassportAuthMiddleware, HTML-view (redirect/exchange/layout). - application:
InitiateSsoLoginHandler,HandleSsoCallbackHandler, команды, DTO, портPassportAuthPort. - infrastructure:
PassportHttpClient— HTTP-реализация порта. - Внешняя система: Passport (SSO/OAuth2).
2. Порт PassportAuthPort
interface PassportAuthPort
{
public function buildAuthorizationUrl(string $state): string; // GET /auth/authorize
public function exchangeAuthorizationCode(string $code): PassportTokenDto; // POST /token
public function refresh(string $refreshToken): PassportTokenDto; // POST /token (refresh)
public function getUser(string $passportId, string $accessToken): PassportUserDto; // GET /users/{id}
public function logout(?string $cookieHeader, ?string $authorization): array; // GET /auth/logout
}
3. Реализация PassportHttpClient
Файл: modules/passport/auth/infrastructure/http/PassportHttpClient.php
Конфигурация (конструктор)
| Аргумент | Откуда |
|---|---|
Client (yii\httpclient) | DI |
baseUrl | params.php['passport_url'] |
clientId | params.php['oauth2_client_id'] |
clientSecret | params.php['oauth2_client_secret'] |
redirectUri | params.php['app_url'] . '/auth/callback' |
scopes | params.php['scopes'] |
userEndpoint | /users/{id} (hardcodе) |
Методы
| Метод | HTTP | Параметры | Ответ |
|---|---|---|---|
buildAuthorizationUrl | — | state | строка URL |
exchangeAuthorizationCode | POST /token | grant_type=authorization_code, code | PassportTokenDto |
refresh | POST /token | grant_type=refresh_token | PassportTokenDto |
getUser | GET /users/{id} | Bearer | PassportUserDto (с обогащением: post через /posts, owner через /roles) |
logout | GET /auth/logout | Cookie/Authorization | массив status/headers/body |
Поведение getUser
- Запрос
GET {base}/users/{id}с Bearer-токеном. - Парсит
item/data(фолбэки). post_id→ доп. запросGET {base}/posts?ids={post_id}для названия должности.is_owner:- из
data.isOwner/data.is_owner; - или по
roles: если встретили запись сname === 'owner'— true; - иначе по
role_id'ам →GET {base}/roles?ids=...ищем роль'owner'.
- из
- Возвращает
PassportUserDto.
Парсинг токенов (parseTokenResponse)
data.access_token→ обязательный;data.refresh_token→ опциональный;data.scope|scopes→ массив (строка разбивается по пробелам);data.expires_in→ default 3600;data.token_type→ default 'Bearer'.
4. DI (config/di.php)
- Проверяет обязательность
OAUTH2_CLIENT_ID,OAUTH2_CLIENT_SECRET,OAUTH2_PUBLIC_KEY_PATH(иначеRuntimeException). Client(yii\httpclient\Client c CurlTransport).PassportAuthPort→PassportHttpClient.InitiateSsoLoginHandler→ построение authorize URL.HandleSsoCallbackHandler→ обмен кода +SyncUserHandler(ядро).PassportAuthMiddleware→ JWT-проверка на запрос.
5. Обработчики
InitiateSsoLoginHandler
handle(InitiateSsoLoginCommand $command): string
// → passport->buildAuthorizationUrl($command->state)
HandleSsoCallbackHandler
handle(HandleSsoCallbackCommand $command): PassportTokenDto
codeпустой → RuntimeException.hash_equals(expectedState, state)— защита CSRF.exchangeAuthorizationCode($code)→ токены.passportClaims($accessToken)— декодирование payload (без проверки подписи; проверка — в middleware).- Берёт
sub, вызываетgetUser($sub, $accessToken). SyncUserHandler->handle(new SyncUserCommand(...))— синхронизация локального пользователя (и роли).- Возвращает токены (контроллер кладёт их в куки).
6. AuthController (presentation)
| Действие | Путь | Поведение |
|---|---|---|
actionLogin | GET /auth/login | state-кука + authorize URL + HTML-редирект |
actionCallback | GET /auth/callback | state-проверка, обмен кода, SyncUser, Set-Cookie токенов, HTML-редирект на фронтенд |
actionLogout | GET /auth/logout | proxy в Passport + чистка кук |
Детали потока — flow.md, безопасность — security.md.