v2: изоляция — свои V2_* env, v2/.env, не трогает основные переменные
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# 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-роутером:
|
||||
```js
|
||||
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`
|
||||
|
||||
### Деплой
|
||||
```bash
|
||||
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
|
||||
|
||||
## Ошибки в процессе
|
||||
|
||||
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)
|
||||
+7
-29
@@ -1,35 +1,13 @@
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// Конфигурация V2
|
||||
//
|
||||
// Приоритет: V2_* → основные → умолчания (локальный KC на ВМ)
|
||||
// Конфигурация V2 — свои переменные (V2_*), не трогает основные
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
require('dotenv').config({ path: require('path').join(__dirname, '..', '..', '..', '.env') });
|
||||
require('dotenv').config({ path: require('path').join(__dirname, '..', '..', '.env') });
|
||||
|
||||
module.exports = {
|
||||
// Keycloak OIDC
|
||||
kcBaseUrl: process.env.V2_KC_BASE_URL
|
||||
|| process.env.KC_BASE_URL
|
||||
|| 'https://italo.kube5s.ru/realms/ipwhitelist',
|
||||
|
||||
kcClientId: process.env.V2_KC_CLIENT_ID
|
||||
|| process.env.KC_CLIENT_ID
|
||||
|| 'ipwhitelist',
|
||||
|
||||
kcClientSecret: process.env.V2_KC_CLIENT_SECRET
|
||||
|| process.env.KC_CLIENT_SECRET
|
||||
|| '',
|
||||
|
||||
// IAM API
|
||||
iamUrl: process.env.V2_IAM_API_URL
|
||||
|| process.env.IAM_API_URL
|
||||
|| 'https://auth-api-dev.ngcloud.ru',
|
||||
|
||||
// Наше приложение (НЕ Keycloak!)
|
||||
appUrl: process.env.V2_APP_URL
|
||||
|| process.env.APP_URL
|
||||
|| 'https://italo.kube5s.ru',
|
||||
|
||||
// Админ
|
||||
adminClientId: process.env.ADMIN_CLIENT_ID || 'WZ01112',
|
||||
kcBaseUrl: process.env.V2_KC_BASE_URL || 'https://italo.kube5s.ru/realms/ipwhitelist',
|
||||
kcClientId: process.env.V2_KC_CLIENT_ID || 'ipwhitelist',
|
||||
kcClientSecret: process.env.V2_KC_CLIENT_SECRET || '',
|
||||
iamUrl: process.env.V2_IAM_API_URL || 'https://auth-api-dev.ngcloud.ru',
|
||||
appUrl: process.env.V2_APP_URL || 'https://italo.kube5s.ru',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user