# Keycloak Auth Reference — консолидированная справка > Обновлено: 2026-06-02 > Файл-ориентир. Править по мере уточнения у DevOps и продвижения проекта. --- ## 1. Keycloak-эндпоинты Realm: **`cloud`** на `keycloak.nubes.ru` | Назначение | URL | |---|---| | Authorization | `https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/auth` | | Token exchange | `https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/token` | | JWKS (сертификаты) | `https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/certs` | | Logout | `https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/logout` | --- ## 2. Зарегистрированное приложение (OAuth client) `client_id` — выдаётся DevOps при регистрации приложения в Keycloak. --- ## 3. Схема аутентификации: Authorization Code Flow ``` 1. Браузер → /login (приложение) 2. Приложение → 302 → Keycloak /auth?client_id=...&scope=openid&redirect_uri=...&state=... 3. Пользователь вводит логин/пароль в Keycloak 4. Пользователь вводит OTP (MFA) 5. Keycloak → 302 → /callback?code=...&state=... 6. Приложение → POST /token (code → access_token + refresh_token + id_token) 7. Валидация JWT через JWKS (RS256) 8. Извлечение claims → req.user → сессия ``` --- ## 4. Получение токена через API Gateway (альтернативный путь) Если в инфраструктуре есть API Gateway, код обменивается не напрямую в Keycloak, а через него: ``` POST /token Content-Type: application/json Body: {"code": ""} ``` --- ## 5. JWT-токены ### 5.1. Пример структуры JWT (deprecated) ``` iss: https:///... aud: sub: name: <ФИО пользователя> email: exp: scope: openid token_type: Bearer ``` > ⚠️ `ClientID` может отсутствовать — зависит от issuer'а. ### 5.2. Пример токена | Поле | Значение | |---|---| | `iss` | `auth-api` | | `ClientID` | `WZ01325` | | `company_id` | `` | | `company_name` | Название компании | | `login` | `user@example.com` | | `email` | `user@example.com` | ### 5.3. Целевой формат токена (из ТЗ) | Claim | Назначение | |---|---| | `ClientID` | Идентификатор компании (WZ-номер) | | `company_id` | UUID компании | | `company_name` | Название компании | | `email` | Email пользователя (для аудита) | | `groups` | ? (пока null) | | `roles` | ? (пока null) | --- ## 6. Роли | Роль | ClientID | Права | |---|---|---| | **Администратор** | `WZ01112` | Все записи, просмотр аудита, экспорт | | **Клиент** | любой другой WZ-номер | Только свои записи | > Как именно ClientID попадает в токен — через группы Keycloak или маппер — **требует уточнения у DevOps**. --- ## 7. Реализация в коде ### `src/auth.js` — два режима | Режим | Условие | Как работает | |---|---|---| | **OIDC** | `KC_CLIENT_ID` + `KC_CLIENT_SECRET` заданы | Authorization Code Flow, JWKS-валидация | | **Mock** | `KC_CLIENT_ID` пусто | Локальная RSA-пара, JWT из `MOCK_USERS` | ### `src/config.js` — Mock-пользователи ```javascript MOCK_USERS = [ { clientId: 'WZ01325', companyName: 'Тест', email: 'tazet@narod.ru' }, { clientId: 'WZ01112', companyName: 'Нубес', email: 'admin@nubes.ru' } ] ``` ### Два слоя аутентификации | Слой | Механизм | Где | |---|---|---| | **UI (EJS)** | Session cookie + PostgreSQL session store | `/`, `/admin`, `/entries` | | **REST API** | Bearer JWT (всегда проверяется явно) | `/api/v1/*` | ### Dev-backdoor - `DEV_MODE=true` или `DEV_SECRET` → `/dev-login` — выбор любого пользователя в обход OIDC/mock --- ## 8. Переменные окружения ```env # Auth DEV_MODE=true JWT_ISSUER=mock-auth-api ADMIN_CLIENT_ID=WZ01112 # OIDC (production) KC_BASE_URL=https://keycloak.nubes.ru/realms/cloud KC_CLIENT_ID= KC_CLIENT_SECRET= APP_URL=http://localhost:3000 # Session SESSION_SECRET=<обязателен в prod> ``` --- ## 9. Открытые вопросы (к DevOps) | # | Вопрос | Статус | |---|---|---| | 1 | Где брать `client_id` и `client_secret` для регистрации приложения в Keycloak? | 🔴 | | 2 | Какой URL JWKS? `auth-api` или `keycloak.nubes.ru`? | 🔴 | | 3 | Когда заполняются `claims.groups` и `claims.roles`? (пока null) | 🔴 | | 4 | Как выглядит токен, если у пользователя несколько компаний? Массив `ClientID`? | 🔴 | | 5 | Есть ли в Keycloak понятие admin-роли? В каком claim? | 🔴 | | 6 | Redirect URI: `https://white.nodejsk8s.dev.nubes.ru/callback` — OK? | 🔴 | | 7 | Кто потребитель `/export`? Какие IP/подсети для allowlist? | 🔴 | | 8 | Формат `jsonEnv` — пример правильного? | 🔴 | --- ## 10. Исходные файлы | Файл | Содержание | |---|---| | `docs/ТЗ.md` | Техническое задание | | `docs/ТЗ-реализация.md` | Карта реализации требований | | `docs/questions-devops.md` | Вопросы к DevOps | | `research/auth-flow.md` | Детальное исследование OIDC-flow | | `research/payg-sso/` | CF-эталон (OAuth2 + JWT RS256) | | `Files/token.txt` | Реальный токен из test-окружения | | `Files/nubes_login.har` | HAR трассировка login-сессии deck-test | | `src/auth.js` | Основной модуль аутентификации | | `src/config.js` | Конфигурация и mock-пользователи |