Files
fission-console/doc/descriptions/auth-flow.md
T

110 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Логика авторизации — Fission Console
## Что вводит пользователь
В форме логина (`index.html`, overlay `#login-overlay`):
- **Стенд** (`#l-env`): `dev` / `test` / `prod`
- **Токен** (`#l-token`): JWT-токен из личного кабинета NUBES (Профиль → Токены)
---
## Фронтенд: `doLogin()` → `js/auth.js`
1. Берёт токен и стенд из формы
2. Делает `POST /console/api/auth` с `{ token, env }` в теле
3. Если ответ OK:
- Сохраняет `auth_token` и `auth_env` в **localStorage** браузера
- Вызывает `setUserAvatar(token)` — декодирует email из JWT payload и показывает в navbar
- Скрывает overlay логина
4. Проверяет `GET /console/api/ns/status` — если namespace не готов, показывает overlay инициализации
---
## Бэкенд: `handleAuth` → `handlers.go:1022`
1. Принимает `POST /console/api/auth`
2. Валидирует токен через `resolveNamespaceForToken(token, env, testMode)`
3. Вызывает `EnsureUserNS` — гарантирует что K8s namespace + RBAC + quota существуют
4. Возвращает JSON: `{ ok: true, env: "test", namespace: "fission-..." }`
---
## Валидация токена: `validateDeckToken` → `server.go:279`
**Deck API** — внешний сервис облачной платформы NUBES:
```
dev → https://deck-api-dev.ngcloud.ru/api/v1
test → https://deck-api-test.ngcloud.ru/api/v1
prod → https://deck-api.ngcloud.ru/api/v1
```
Проверка: `GET {deckAPI}/index.cfm/instances` с заголовком `Authorization: Bearer {token}`
- `401` → токен невалиден
- Любой другой ответ → токен принят
- Результат кэшируется на **5 минут** (`sync.Map`)
---
## Вычисление namespace: `namespaceFromJWT` → `auth.go:131`
1. JWT токен **не верифицируется по подписи** — Deck API уже это сделал
2. Декодируется payload (base64url)
3. Извлекается claim `"sub"` (идентификатор пользователя в облаке)
4. Namespace = `"fission-" + hex(SHA256(sub)[:8])`
Пример: sub = `c3fce59430e41b0f...` → namespace `fission-c3fce59430e41b0f`
---
## Email в navbar: `setUserAvatar` / `jwtEmail` → `auth.js`
- `jwtEmail(token)` — декодирует JWT payload на **фронтенде** (без обращения к серверу)
- Берёт `payload.email` или `payload.sub`
- Отображает в `#user-avatar` в левом верхнем углу (вместо синего кружка)
---
## Последующие запросы
Каждый API-запрос от фронтенда включает заголовки:
```
X-Auth-Token: <токен из localStorage>
X-Auth-Env: <стенд из localStorage>
```
`authMiddleware` (`auth.go`) снова валидирует токен (но из кэша — без нового HTTP-запроса к Deck API),
вычисляет namespace и кладёт его в `context.Context` → все хендлеры работают в нужном namespace.
---
## Test-режим (FISSION_TEST_MODE=true)
Вместо реального Deck API — проверяет заголовок `X-Test-Sub`.
Если токен содержит `@` — трактуется как email и используется как sub для вычисления namespace.
Используется в тестах и для live-тестирования без реальных токенов.
---
## Итого — схема
```
Пользователь вводит токен + стенд
POST /console/api/auth
├─► validateDeckToken → Deck API ({env}.ngcloud.ru) → 200 = ОК
├─► namespaceFromJWT → decode JWT payload → claim "sub" → SHA256[:8] → "fission-XXXXXXXX"
├─► EnsureUserNS → K8s namespace + RBAC создаются если нет
└─► { ok: true, namespace: "fission-..." }
Фронтенд:
├─► localStorage.setItem('auth_token', token)
├─► localStorage.setItem('auth_env', env)
├─► jwtEmail(token) → email из JWT payload → показать в navbar
└─► reloadAll() — загрузить функции
```