5.2 KiB
5.2 KiB
V2 — история 2026-06-12
Цель
Перепроектирование ipwhitelist-app. Начали с модуля аутентификации: Keycloak OIDC → IAM API → готовый sessionUser.
Архитектура
Принцип
Один вызов login() при логине. После этого ни Keycloak, ни IAM не нужны.
Переключение компаний — только в сессии (не через IAM switchProfile).
Ответ IAM (/api/v1/auth/user)
См. Files/architect.md — задокументированы все поля.
Два стенда
| Стенд | URL | Keycloak | IAM |
|---|---|---|---|
| Production | whitelist.nodejsk8s.services.ngcloud.ru |
prod-KC | ✅ |
| VM (тест) | italo.kube5s.ru |
локальный KC на :8080 | ❌ |
clientId vs companyId
clientId= WZ01112 (W-номер) — идентификатор компании в БДcompanyId= внутренний ID IAM, не W-формат, почти не используетсяallClientIds= массив всех W-номеров (собираем изprofiles[].client_id)
Созданные файлы
v2/
├── server.js # createV2Router() — монтируется в server.js как /v2
├── src/
│ ├── config/index.js # приоритет: V2_KC_* → KC_* → умолчания
│ └── auth/index.js # login(), fetchIamUser(), exchangeCode(), buildAuthUrl(), generateState()
└── history/
└── 2026-06-12.md # этот файл
v2/src/auth/index.js — функции
| Функция | Что | Вызывается |
|---|---|---|
buildAuthUrl(config) |
URL редиректа на Keycloak | GET /v2/login |
exchangeCode(code, config) |
code → access_token | внутри login() |
fetchIamUser(token, iamUrl) |
IAM → профиль | внутри login() |
generateState() |
CSRF-токен | GET /v2/login |
login(code, oidcConfig, iamUrl) |
оркестратор: всё сразу | GET /v2/callback |
v2/src/config/index.js — приоритет
V2_KC_BASE_URL → KC_BASE_URL → https://italo.kube5s.ru/realms/ipwhitelist
V2_KC_CLIENT_ID → KC_CLIENT_ID → ipwhitelist
V2_KC_CLIENT_SECRET → KC_CLIENT_SECRET → ''
V2_APP_URL → APP_URL → https://italo.kube5s.ru
V2_IAM_API_URL → IAM_API_URL → https://auth-api-dev.ngcloud.ru
v2/server.js — роуты
| Путь | Что |
|---|---|
GET /v2/ |
главная: IAM-данные или редирект на /v2/login |
GET /v2/login |
→ Keycloak |
GET /v2/callback |
Keycloak → code → login() → сессия → /v2/ |
GET /v2/logout |
сброс v2_ ключей сессии |
Сессионные ключи с префиксом v2_: v2_user, v2_token, v2_idToken, v2_oidcState.
Не пересекаются с основным приложением.
server.js — изменения
Добавлено перед UI-роутером:
const { createV2Router } = require('./v2/server');
app.use('/v2', createV2Router());
Порядок: /healthz → OIDC → /api/v1/* → /v2/* → UI (/*)
Что сделано на VM (italo.kube5s.ru)
Keycloak
- Realm
ipwhitelist, frontendUrl=https://italo.kube5s.ru - Client
ipwhitelist, redirectUris=['https://italo.kube5s.ru/v2/callback'] - Пользователь:
test/test - Client secret:
40bpIZvumq6jttIB5QtTLcl9AJvAHxlw - Доступ через nginx:
/realms/*→ Keycloak:8080
.env на ВМ
Добавлено: V2_KC_CLIENT_SECRET=40bpIZvumq6jttIB5QtTLcl9AJvAHxlw
Деплой
rsync -az -e "ssh ..." /home/naeel/ipwhitelist-app/v2 naeel@5.172.178.213:~/ipwhitelist/
ssh ... 'pm2 restart ipwhitelist'
Git
- Версия:
0.5.57→0.5.58 - Коммит:
5c09844— v2: модуль аутентификации + роутер /v2 - Запушено в
masterна gitea.services.ngcloud.ru
Ошибки в процессе
rsync v2/с trailing slash → содержимое v2/ скопировалось в~/ipwhitelist/, v2/server.js перезаписал основной server.js- Fix: rsync без trailing slash (
rsync ... v2)
- Fix: rsync без trailing slash (
sedзаменил оба вхожденияitalo.kube5s.ruв конфиге (kcBaseUrl и appUrl)- Fix: переписал файл полностью
kcBaseUrlбез/realms/ipwhitelist→ редирект на неверный URL Keycloak- Fix:
https://italo.kube5s.ru/realms/ipwhitelist
- Fix:
- На ВМ старый
ui/index.jsс багом (дубликат catch) → краш приложения- Fix: rsync --force ui/index.js
Что дальше
- Дождаться редеплоя на production (Nubes UI)
- Проверить
https://whitelist.nodejsk8s.services.ngcloud.ru/v2/login - Если prod-KC не разрешает
/v2/callback→ добавить в VM-шный KC и задать V2_KC_BASE_URL на production - Реализовать IAM-фолбэк (если IAM недоступен → JWT claims)