96 lines
4.4 KiB
Markdown
96 lines
4.4 KiB
Markdown
# Архитектура авторизации облачного портала
|
||
|
||
> ✅ ПРОВЕРЕНО: API успешно вызван через curl 2026-05-29.
|
||
|
||
---
|
||
|
||
## Схема аутентификации
|
||
|
||
```
|
||
Пользователь (браузер)
|
||
│
|
||
▼
|
||
Keycloak (keycloak.nubes.ru, realm=cloud)
|
||
│ Authorization Code Flow
|
||
│ client_id=deck.ngcloud.ru
|
||
│ scope=openid email
|
||
▼
|
||
auth-api.ngcloud.ru (СОБСТВЕННЫЙ сервис)
|
||
│ Создаёт свой JWT (issuer="auth-api")
|
||
│ Подпись: RS256 (RSA)
|
||
▼
|
||
deck.ngcloud.ru (портал)
|
||
│ Микро-фронтенды (SPA): dashboard, contracts, services, ...
|
||
│ JWT хранится в localStorage: authApiTokens.access_token
|
||
▼
|
||
IPWhiteList (наш сервис) ← будет встроен как микро-фронтенд в портал
|
||
```
|
||
|
||
## Важное
|
||
|
||
- JWT подписывает **не Keycloak**, а **auth-api**
|
||
- Issuer: `"auth-api"`, алгоритм: `RS256`
|
||
- Для валидации нужен публичный ключ auth-api (JWKS или статический)
|
||
|
||
---
|
||
|
||
## Структура JWT (access_token)
|
||
|
||
_Из localStorage → authApiTokens → access_token_
|
||
|
||
| Поле | Тип | Значение (пример) | Назначение |
|
||
|---|---|---|---|
|
||
| `iss` | string | `"auth-api"` | Кто выпустил токен |
|
||
| `sub` | string | `"0199e325-..."` | UUID пользователя |
|
||
| `iat` | number | `1780073927` | Выпущен (Unix time) |
|
||
| `exp` | number | `1780117127` | Истекает (~12 часов) |
|
||
| `jti` | string | `"4d8d7240-..."` | Уникальный ID токена |
|
||
| `ClientID` | string | `"WZ01325"` | ID **ТЕКУЩЕЙ** компании пользователя |
|
||
| `company_id` | string (UUID) | `"3e64aac6-..."` | UUID компании |
|
||
| `company_name` | string | `"Тест"` | Название компании |
|
||
| `email` | string | `"tazet@narod.ru"` | Email (для аудита) |
|
||
| `login` | string | `"tazet@narod.ru"` | Логин |
|
||
| `firstname` | string | `"Наиль"` | Имя |
|
||
| `lastname` | string | `"Тазетдинов"` | Фамилия |
|
||
| `token_type` | string | `"access"` | Тип токена |
|
||
|
||
## Что НЕ в JWT (отдельный authData в localStorage)
|
||
|
||
_Из localStorage → authData → v_
|
||
|
||
| Поле | Значение | Где используется |
|
||
|---|---|---|
|
||
| `userInfo.isAdmin` | `false` (boolean) | ⚠️ Признак администратора |
|
||
| `profiles[]` | Массив `{company_id, company_name, is_active_profile}` | Список всех компаний пользователя |
|
||
| `roles[]` | Массив `{role_id, role_name}` | Роли пользователя |
|
||
| `permissions.can_write` | `false` | Есть ли права на запись |
|
||
|
||
---
|
||
|
||
## Открытые вопросы (нужно уточнить с командой портала)
|
||
|
||
1. **Валидация JWT.** ✅ Выяснено: API gateway (`lk-api-gateway.ngcloud.ru`) сам валидирует JWT через auth-api. Нам достаточно передавать `Authorization: Bearer <JWT>`.
|
||
|
||
2. **isAdmin.** Флаг админа есть только в authData localStorage, но не в JWT. Как наш сервис узнает что пользователь — админ?
|
||
- Нужно уточнить: можно ли добавить `isAdmin` в JWT или получать через API gateway
|
||
|
||
3. **Список компаний.** В JWT — только одна компания. В authData.profiles — массив. Для переключателя компаний — откуда брать список?
|
||
|
||
4. **Монтирование в API gateway.** Наш сервис будет за `lk-api-gateway.ngcloud.ru` как отдельный route (например `/api/v1/whitelist/...`). Нужно уточнить процедуру добавления нового route.
|
||
|
||
---
|
||
|
||
## Как вызывать API (проверено curl'ом)
|
||
|
||
```bash
|
||
curl -H "Authorization: Bearer <JWT>" \
|
||
-H "Origin: https://deck.ngcloud.ru" \
|
||
-H "Cookie: __ddg1_=...; __ddg8_=...; __ddg9_=...; __ddg10_=..." \
|
||
"https://lk-api-gateway.ngcloud.ru/api/v1/..."
|
||
```
|
||
|
||
- **API Gateway:** `lk-api-gateway.ngcloud.ru` (не deck-api.ngcloud.ru!)
|
||
- **DDOS-Guard cookies ОБЯЗАТЕЛЬНЫ** (без них 403)
|
||
- **JWT issuer:** `auth-api`
|
||
- **Алгоритм:** RS256
|