Files
NeveTimePanel/СХЕМА_РАБОТЫ.md
2026-01-15 09:32:13 +06:00

283 lines
11 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.
# 🔄 Схема работы OpenID Connect с ZITADEL
## Визуальная схема
```
┌─────────────┐
│ Пользователь│
└──────┬──────┘
│ 1. Открывает страницу входа
┌─────────────────────────────────────┐
│ Frontend (React) │
│ http://localhost:3000 │
│ │
│ ┌───────────────────────────────┐ │
│ │ Форма входа │ │
│ │ - Логин/Пароль │ │
│ │ - Кнопка ZITADEL 🔐 │ │
│ └───────────────────────────────┘ │
└──────────────┬──────────────────────┘
│ 2. Нажимает "Войти через ZITADEL"
│ GET /api/auth/oidc/zitadel/login
┌─────────────────────────────────────┐
│ Backend (FastAPI) │
│ http://localhost:8000 │
│ │
│ ┌───────────────────────────────┐ │
│ │ OAuth Client │ │
│ │ - Создаёт authorize URL │ │
│ │ - Добавляет state, nonce │ │
│ └───────────────────────────────┘ │
└──────────────┬──────────────────────┘
│ 3. Redirect на ZITADEL
┌─────────────────────────────────────┐
│ ZITADEL │
│ https://your-instance.zitadel.cloud│
│ │
│ ┌───────────────────────────────┐ │
│ │ Страница входа │ │
│ │ - Email/Username │ │
│ │ - Password │ │
│ │ - 2FA (опционально) │ │
│ └───────────────────────────────┘ │
└──────────────┬──────────────────────┘
│ 4. Пользователь вводит данные
│ 5. ZITADEL проверяет
│ 6. Redirect с code
┌─────────────────────────────────────┐
│ Backend (FastAPI) │
│ /api/auth/oidc/zitadel/callback │
│ │
│ ┌───────────────────────────────┐ │
│ │ 7. Обмен code на token │ │
│ │ POST /oauth/token │ │
│ └───────────────────────────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ 8. Получение userinfo │ │
│ │ - email │ │
│ │ - name │ │
│ │ - sub (user ID) │ │
│ └───────────────────────────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ 9. Создание/обновление │ │
│ │ пользователя в users.json │ │
│ └───────────────────────────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ 10. Генерация JWT токена │ │
│ │ для MC Panel │ │
│ └───────────────────────────────┘ │
└──────────────┬──────────────────────┘
│ 11. Redirect на frontend
│ ?token=xxx&username=yyy
┌─────────────────────────────────────┐
│ Frontend (React) │
│ │
│ ┌───────────────────────────────┐ │
│ │ 12. Обработка callback │ │
│ │ - Извлечение token │ │
│ │ - Сохранение в localStorage│ │
│ │ - Очистка URL │ │
│ └───────────────────────────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ 13. Автоматический вход │ │
│ │ - Загрузка данных │ │
│ │ - Показ панели │ │
│ └───────────────────────────────┘ │
└──────────────┬──────────────────────┘
│ 14. Пользователь в системе!
┌─────────────────────────────────────┐
│ MC Panel Dashboard │
│ - Серверы │
│ - Тикеты │
│ - Личный кабинет │
└─────────────────────────────────────┘
```
## Детальный поток данных
### Шаг 1-2: Инициация входа
```
Пользователь → Frontend
Frontend → Backend: GET /api/auth/oidc/zitadel/login
Backend создаёт OAuth URL:
- client_id
- redirect_uri
- scope: openid email profile
- state (CSRF защита)
- nonce (replay защита)
```
### Шаг 3-6: Аутентификация в ZITADEL
```
Backend → ZITADEL: Redirect на /oauth/authorize
ZITADEL показывает форму входа
Пользователь вводит данные
ZITADEL проверяет учётные данные
ZITADEL → Backend: Redirect с code
URL: /callback?code=xxx&state=yyy
```
### Шаг 7-8: Получение данных
```
Backend → ZITADEL: POST /oauth/token
Параметры:
- code
- client_id
- client_secret
- redirect_uri
ZITADEL → Backend: access_token + id_token
Backend извлекает userinfo:
{
"sub": "123456789012345678",
"email": "user@example.com",
"name": "John Doe",
"picture": "https://..."
}
```
### Шаг 9-10: Создание пользователя
```
Backend проверяет users.json:
- Ищет по oidc_id = "zitadel:123456789012345678"
Если найден:
- Обновляет email, name, picture
Если не найден:
- Создаёт нового пользователя
- Генерирует username из email
- Роль: "user"
- Пустой пароль (OIDC пользователь)
Backend создаёт JWT токен:
{
"sub": "john_doe",
"role": "user",
"exp": 1234567890
}
```
### Шаг 11-14: Возврат в приложение
```
Backend → Frontend: Redirect
URL: http://localhost:3000/?token=xxx&username=yyy
Frontend (useEffect):
- Извлекает token и username из URL
- Сохраняет в localStorage
- Очищает URL (history.replaceState)
- Обновляет состояние (setToken, setUser)
Frontend загружает данные:
- GET /api/auth/me (проверка токена)
- GET /api/servers (список серверов)
Пользователь видит панель управления
```
## Структура данных
### ZITADEL userinfo
```json
{
"sub": "123456789012345678",
"email": "user@example.com",
"email_verified": true,
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"picture": "https://avatar.url",
"locale": "en"
}
```
### MC Panel user (users.json)
```json
{
"john_doe": {
"username": "john_doe",
"password": "",
"role": "user",
"servers": [],
"oidc_id": "zitadel:123456789012345678",
"email": "user@example.com",
"name": "John Doe",
"picture": "https://avatar.url",
"provider": "zitadel",
"created_at": "2026-01-15T12:00:00"
}
}
```
### JWT токен (MC Panel)
```json
{
"sub": "john_doe",
"role": "user",
"exp": 1737820800,
"iat": 1737216000
}
```
## Безопасность
### Защита от атак
1. **CSRF (Cross-Site Request Forgery)**
- State parameter проверяется
- Случайное значение для каждого запроса
2. **Replay атаки**
- Nonce в id_token
- Одноразовое использование code
3. **Man-in-the-Middle**
- HTTPS обязателен в продакшене
- Проверка redirect_uri
4. **Token theft**
- JWT с истечением (7 дней)
- Хранение в localStorage (XSS защита нужна)
### Рекомендации для продакшена
```
✓ Использовать HTTPS
✓ Настроить CORS правильно
✓ Добавить rate limiting
✓ Логировать все входы
✓ Мониторить подозрительную активность
✓ Регулярно обновлять client_secret
✓ Использовать refresh tokens
```
## Готово! 🎉
Схема показывает полный цикл аутентификации через ZITADEL.
**Всё работает автоматически и безопасно!** 🔐