Files
auth-portal/docs/integrate-mikrotikmanager.md
DenozordecandCursor fd7d9fd13c
quality / commitlint (push) Skipped
quality / changes (push) Successful in 7s
quality / docker-check (push) Skipped
quality / web (push) Successful in 40s
quality / api (push) Successful in 36s
CD / quality (push) Successful in 1m37s
CD / publish (push) Successful in 1m40s
feat(apps): добавить MikrotikManager app id mm
Регистрация mm в каталоге приложений, permissions mm:*, target-app и docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 20:38:27 +07:00

3.8 KiB
Raw Permalink Blame History

Интеграция auth-portal ↔ MikrotikManager

Единый вход: пользователь логинится на auth-portal, получает JWT, переходит в MikrotikManager с токеном в URL fragment. Backend MM проверяет JWT и права mm:*.

Архитектура

Browser → MikrotikManager UI (нет token)
       → redirect AUTH_PORTAL_URL/?return_to=…/auth/callback
       → login
       → redirect return_to#access_token=…
       → MM /auth/callback сохраняет token (mmapp_token)
       → API Authorization: Bearer …

Общий секрет: JWT_SECRET / AUTH_JWT_SECRET (HS256). Issuer: ISSUER / AUTH_ISSUER.

App id в портале: mm (каталог permissions).

Локальный запуск

1. auth-portal

cd auth-portal
pnpm install
# JWT_SECRET=dev-secret-change-me
# RETURN_TO_ALLOWLIST=.shnt.top,localhost,http://localhost:3000
pnpm --filter @authportal/api dev   # :8080
pnpm --filter web dev               # :5175

Bootstrap: admin@shnt.top / admin. В админке выдайте app mm и permissions mm:*.

2. MikrotikManager

cd MikrotikManager
npm install

Backend backend/.env:

AUTH_REQUIRED=true
AUTH_JWT_SECRET=dev-secret-change-me
AUTH_ISSUER=https://auth.shnt.top
AUTH_PORTAL_URL=http://localhost:5175
CORS_ORIGIN=http://localhost:3000

Frontend: NEXT_PUBLIC_AUTH_PORTAL_URL=http://localhost:5175 (или runtime GET /api/auth/config через proxy).

npm --prefix backend run dev
npm run dev

Откройте http://localhost:3000 → редирект на portal → после логина NavUser показывает имя/email.

Permissions ↔ API / UI

Иерархия: adminwriteread в рамках одной секции.

Permission API (prefix) UI
mm:dashboard:read sidebar-counts, events (GET) /dashboard
mm:servers:read / write /api/servers* /servers
mm:filters:read / write /api/filters* /filters, GRE
mm:bgp:read / write /api/bgp* BGP
mm:uptime:read / write /api/uptime* /uptime
mm:traffic:read / write /api/traffic* /traffic
mm:alerts:read / write /api/alerts* /alerts
mm:backups:read / write /api/backups* /backups
mm:certificates:read / write /api/certificates* certificates
mm:network:read / write /api/network*, OSPF, recursive, probes network
mm:settings:admin /api/system/*, scheduler, evobgp settings /settings

Без app mm в JWT apps403 на защищённые /api/*.

AUTH_REQUIRED=false — API открыт (dev без portal).

App Switcher

CURRENT_APP_ID = mm. Публичный конфиг: GET {AUTH_PORTAL_URL}/api/v1/app-switcher.

Logout (SSO)

Очистить mmapp_token → редирект на {AUTH_PORTAL_URL}/logout.

Production

См. общий стек CDN+MM: deploy/docker-compose.cdn-mm.yml / deploy/env.cdn-mm.example.

AUTH_REQUIRED=true
AUTH_JWT_SECRET=<тот же JWT_SECRET портала>
AUTH_ISSUER=https://auth.shnt.top
AUTH_PORTAL_URL=https://auth.shnt.top
CORS_ORIGIN=https://mm.shnt.top

В portal: RETURN_TO_ALLOWLIST включает https://mm.shnt.top (или .shnt.top).

Troubleshooting

Симптом Причина
SSO loop разный JWT_SECRET или ISSUER
403 «Нет доступа к приложению» нет app mm у пользователя
403 «Недостаточно прав» нет нужного mm:…
return_to rejected origin MM не в RETURN_TO_ALLOWLIST