zitadel auth

This commit is contained in:
Codex
2026-05-01 19:57:04 +03:00
parent 54b0f07794
commit c1654236c9
2 changed files with 632 additions and 272 deletions

106
README.md Normal file
View File

@@ -0,0 +1,106 @@
# ZITADEL POC
POC с кастомными формами `login` и `register`, где ZITADEL используется только как backend IdP.
- `/login` — кастомная форма входа
- `/register` — кастомная форма регистрации
- `/me` — JSON с claims из JWT, выданного ZITADEL
- `/dashboard` — UI, который показывает данные из `/me`
Приложение не использует hosted login UI ZITADEL для пользовательского входа:
- не используется `/ui/login/loginname`
- не используется `/ui/login/password`
- не парсится hosted HTML, CSRF или `authRequestID` старого hosted login
- браузер не уходит на hosted SSO-страницы ZITADEL при входе через `http://localhost:3001/login`
Пароли и учетные записи хранятся в ZITADEL, не в нашем приложении.
## Запуск
```bash
docker compose down -v
docker compose up --build
```
Первый запуск ZITADEL может занять несколько минут.
## Адреса
Frontend:
```txt
http://localhost:3001
```
ZITADEL Console:
```txt
http://zitadel.localhost:8081
```
## Как работает вход
1. Регистрация создает пользователя в ZITADEL через API:
```txt
POST /v2/users/human
```
2. Вход проверяет `email/password` через официальный Session API ZITADEL:
```txt
POST /v2/sessions
PATCH /v2/sessions/{sessionId}
```
3. После успешной аутентификации backend завершает OIDC auth request и получает настоящий `id_token` / `access_token` от ZITADEL.
4. `/me` валидирует и декодирует `id_token`, затем возвращает только claims:
- `sub`
- `email`
- `name`
- `preferred_username`
- `iss`
- `aud`
- `iat`
- `exp`
5. `/dashboard` показывает именно JSON из `/me`, а не raw JWT.
## Хранение токенов
- токены не хранятся в `localStorage`
- токены не хранятся в `sessionStorage`
- используется `HttpOnly` cookie
- используется `SameSite=Lax`
- в production cookie должна быть `Secure=true`
- в local dev `Secure=false`
## Password Policy
Локальная валидация и ZITADEL policy выровнены под тот же набор правил, что и в проекте Authentik:
- минимум 8 символов
- хотя бы одна заглавная буква
- хотя бы одна строчная буква
- хотя бы одна цифра
## Logout
```txt
POST /logout
```
Этот endpoint очищает cookie приложения и закрывает ZITADEL session, если она есть.
## Out Of Scope
В рамках этого POC не реализованы:
- sessions UI
- consent UI
- MFA devices UI
- connected services
- app passwords

File diff suppressed because it is too large Load Diff