Files
ipwhitelist-app/v2/history/2026-06-12.md
T

5.2 KiB
Raw Blame History

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.570.5.58
  • Коммит: 5c09844 — v2: модуль аутентификации + роутер /v2
  • Запушено в master на gitea.services.ngcloud.ru

Ошибки в процессе

  1. rsync v2/ с trailing slash → содержимое v2/ скопировалось в ~/ipwhitelist/, v2/server.js перезаписал основной server.js
    • Fix: rsync без trailing slash (rsync ... v2)
  2. sed заменил оба вхождения italo.kube5s.ru в конфиге (kcBaseUrl и appUrl)
    • Fix: переписал файл полностью
  3. kcBaseUrl без /realms/ipwhitelist → редирект на неверный URL Keycloak
    • Fix: https://italo.kube5s.ru/realms/ipwhitelist
  4. На ВМ старый ui/index.js с багом (дубликат catch) → краш приложения
    • Fix: rsync --force ui/index.js

Что дальше

  1. Дождаться редеплоя на production (Nubes UI)
  2. Проверить https://whitelist.nodejsk8s.services.ngcloud.ru/v2/login
  3. Если prod-KC не разрешает /v2/callback → добавить в VM-шный KC и задать V2_KC_BASE_URL на production
  4. Реализовать IAM-фолбэк (если IAM недоступен → JWT claims)