25c6e9444b14bc904e7e3a43a0072c697f919521
SSO Service
Self-hosted SSO / OIDC-сервис — аналог Keycloak / Яндекс ID. Node.js (NestJS).
Технологии
- Runtime: Node.js 22, NestJS 11
- Database: PostgreSQL 16 + Prisma ORM
- Cache: Redis 7
- Message Broker: RabbitMQ 4
- Logging: Pino (JSON, nestjs-pino)
- Metrics: Prometheus
- Security: Argon2, JWT (Access + Refresh), Helmet, OIDC (authorization_code, PKCE)
- Templates: EJS + Bootstrap 5
Возможности
Аутентификация
- Логин/пароль (Argon2)
- Вход по коду на email
- Вход по коду на телефон
- QR-авторизация (для мобильного приложения)
- Refresh + rotate токенов
Веб-панель
/login— страница входа (пароль, код на email, QR)/register— регистрация/profile— личный кабинет (редактирование профиля)/admin— админ-панель:- Статистика (пользователи, клиенты, сессии)
- CRUD пользователей
- CRUD OAuth-клиентов (как oauth.yandex.ru)
Роли
- USER — только свой профиль
- ADMIN — управление пользователями и OAuth-клиентами
OIDC / OAuth2
/authorize(authorization_code)/token(authorization_code, refresh_token, client_credentials)/userinfo/revoke- PKCE support
Быстрая установка (чистый сервер — всё включено)
Одна команда — установит Node.js 22, Docker, сам сервис и запустит:
curl -fsSL https://git.lendry.ru/lendry/sso-mvk/raw/branch/main/install.sh | bash
Скрипт автоматически:
- Определяет ОС (Ubuntu/Debian/RHEL/CentOS/Fedora)
- Устанавливает Docker + Docker Compose plugin (если нет)
- Устанавливает Node.js 22 LTS (через NodeSource или nvm)
- Скачивает SSO Service в
~/sso-service - Генерирует
.envсо случайными JWT-секретами - Запускает PostgreSQL, Redis, RabbitMQ (ждёт готовности)
- Устанавливает npm-зависимости, Prisma client, применяет миграции
- Сидирует БД (администратор и тестовый OAuth-клиент)
- Собирает и запускает сервис (PM2 или background)
Через 2-3 минуты сервис доступен: http://localhost:3000
Ручная установка (если нужен контроль)
docker compose up -d
npx prisma db push
npx ts-node prisma/seed.ts
npm run start:dev
API Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/auth/register | No | Регистрация |
| POST | /api/auth/login | No | Логин (пароль) |
| POST | /api/auth/login/email-code | No | Логин (код на email) |
| POST | /api/auth/login/phone-code | No | Логин (код на телефон) |
| POST | /api/auth/send-email-code | No | Отправить код на email |
| POST | /api/auth/send-phone-code | No | Отправить код на телефон |
| POST | /api/auth/qr/init | No | Создать QR-сессию |
| POST | /api/auth/qr/poll | No | Проверить QR-сессию |
| POST | /api/auth/refresh | No | Обновить токен |
| POST | /api/auth/logout | No | Выйти |
| GET | /api/auth/profile | JWT | Профиль |
| POST | /api/auth/profile/update | JWT | Обновить профиль |
| GET | /api/authorize | No | OAuth2 authorize |
| POST | /api/token | No | OAuth2 token |
| GET | /api/userinfo | Bearer | OIDC userinfo |
| POST | /api/revoke | No | Отозвать токен |
| GET | /api/admin/stats | JWT+ADMIN | Статистика |
| GET | /api/admin/users | JWT+ADMIN | Список пользователей |
| POST | /api/admin/users | JWT+ADMIN | Создать пользователя |
| PUT | /api/admin/users/:id | JWT+ADMIN | Обновить пользователя |
| DELETE | /api/admin/users/:id | JWT+ADMIN | Удалить пользователя |
| GET | /api/admin/clients | JWT+ADMIN | Список OAuth-клиентов |
| POST | /api/admin/clients | JWT+ADMIN | Создать OAuth-клиент |
| PUT | /api/admin/clients/:id | JWT+ADMIN | Обновить OAuth-клиент |
| DELETE | /api/admin/clients/:id | JWT+ADMIN | Удалить OAuth-клиент |
| GET | /metrics | No | Prometheus метрики |
Веб-панель
| Страница | URL | Доступ |
|---|---|---|
| Логин | /login | Все |
| Регистрация | /register | Все |
| Профиль | /profile | Авторизованные |
| Админка (пользователи) | /admin | ADMIN |
| Админка (клиенты) | /admin/clients | ADMIN |
Примеры cURL
Регистрация
curl -X POST http://localhost:3000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"secret1234","displayName":"Test"}'
Логин по паролю
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"secret1234"}'
Логин по коду на email
# Шаг 1: запросить код
curl -X POST http://localhost:3000/api/auth/send-email-code \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com"}'
# Шаг 2: войти с кодом
curl -X POST http://localhost:3000/api/auth/login/email-code \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","code":"123456"}'
QR-авторизация
# Инициализация
curl -X POST http://localhost:3000/api/auth/qr/init
# Проверка статуса
curl -X POST http://localhost:3000/api/auth/qr/poll \
-H "Content-Type: application/json" \
-d '{"sessionId":"<sessionId>"}'
Админка (список пользователей)
curl http://localhost:3000/api/admin/users \
-H "Authorization: Bearer <admin_token>"
Метрики
curl http://localhost:3000/metrics
RabbitMQ Management
http://localhost:15672
Login: sso / sso_secret
Переменные окружения
Скопируйте .env.example в .env:
cp .env.example .env
Все переменные строго валидируются (Zod). Fast Fail.
Быстрая установка одной командой
curl -fsSL https://git.lendry.ru/lendry/sso-mvk/raw/main/install.sh | bash
Скрипт автоматически:
- Проверяет Node.js, Docker, Docker Compose
- Скачивает проект в
~/sso-service - Создаёт
.envсо случайными JWT-секретами - Запускает PostgreSQL, Redis, RabbitMQ через Docker
- Устанавливает зависимости, применяет миграции, сидирует БД
- Собирает и запускает сервис
После установки:
- Веб-панель: http://localhost:3000
- Админ:
admin@sso.local/admin123! - Метрики: http://localhost:3000/metrics
- RabbitMQ UI: http://localhost:15672 (
sso/sso_secret)
Переменные окружения (опционально)
INSTALL_DIR=/opt/sso curl -fsSL https://git.lendry.ru/lendry/sso-mvk/raw/branch/main/install.sh | bash
Ручная установка
# 1. Клонировать
git clone https://git.lendry.ru/lendry/sso-mvk.git
cd sso-service
# 2. Настроить окружение
cp .env.example .env
# Отредактировать .env под себя
# 3. Запустить инфраструктуру
docker compose up -d
# 4. Установить зависимости и применить миграции
npm ci
npx prisma generate
npx prisma db push
npx ts-node prisma/seed.ts
# 5. Собрать и запустить
npm run build
node dist/main
Production-деплой
npm run build
node dist/main
Корректно обрабатывает X-Forwarded-For (TRUST_PROXY).
Публикация на Gitea
# 1. Создать репозиторий на https://git.lendry.ru → New repository
# Название: sso-mvk (или любое другое)
# Visibility: Public
# 2. Инициализировать git и запушить
cd sso-mvk
git init
git add -A
git commit -m "Initial commit: SSO service (NestJS, Prisma 7, PostgreSQL)"
git branch -M main
git remote add origin https://git.lendry.ru/lendry/sso-mvk.git
git push -u origin main
# 3. Установка с любого сервера:
curl -fsSL https://git.lendry.ru/lendry/sso-mvk/raw/branch/main/install.sh | bash
Важно: Перед пушем проверьте install.sh — REPO="lendry/sso-mvk" и GIT_HOST="git.lendry.ru" должны соответствовать вашему Gitea.
Description
Languages
TypeScript
64.5%
EJS
21.5%
Shell
12.6%
JavaScript
0.8%
Dockerfile
0.4%
Other
0.2%