Агуулгыг алгасах

eID нэвтрэлт

Платформ дээр нууц үг байхгүй. Бүртгүүлэх маягт, и-мэйл OTP, нууц үг сэргээх урсгал ч байхгүй — identity зөвхөн гадаад эх сурвалжаас ирнэ.

Арга Юу Төлөв
eID Mongolia Цахим үнэмлэхээр баталгаажих (QR / App2App / РД push) Үндсэн арга
Google OAuth eID-ээр баталгаажсаны дараа данс холбох Дагалдах
Gerege SSO (OIDC) Экосистемийн provider-оор нэвтрэх Сонголттой

1. eID-ээр нэвтрэх

Апп нь eID Mongolia-ийн Relying Party (pkg/eid, EID_* тохиргоо).

sequenceDiagram
  participant U as Иргэн
  participant W as Web (BFF)
  participant A as Go API
  participant E as eID Mongolia
  U->>W: «eID-ээр нэвтрэх»
  W->>A: POST /v1/auth/eid/start (эсвэл /start-id)
  A->>E: session эхлүүлэх
  E-->>A: session id + QR / deep-link
  A-->>W: QR код · deep-link · sid
  U->>E: QR уншуулах / апп нээх / push зөвшөөрөх
  loop ~2.5с тутам (IdP-г 25с хүртэл барина)
    W->>A: POST /v1/auth/eid/poll {sid}
    A->>E: session төлөв?
  end
  E-->>A: COMPLETE + иргэний өгөгдөл
  A->>A: users upsert (civil_id-ээр)
  A-->>W: access + refresh токен
  W-->>U: httpOnly cookie тавьж dashboard руу
Endpoint Юу
POST /api/v1/auth/eid/start Session эхлүүлж QR код + мобайл deep-link буцаана
POST /api/v1/auth/eid/start-id Иргэний РД-аар эхлүүлж, бүртгэлтэй төхөөрөмж рүү push
POST /api/v1/auth/eid/poll Frontend long-poll хийнэ; COMPLETE болтол хүлээнэ
GET /api/v1/auth/status/{sid} Session-ийн төлөв шалгах

Яагаад long-poll вэ?

Frontend ~2.5 секунд тутамд poll хийж, backend нь IdP-г нэг poll дотор 25 секунд хүртэл барина. Ингэснээр сүлжээний ачаалал бага, хариу үйлдэл шуурхай хоёулаа хангагдана. Энэ замд өөрийн rate limiter (~60/мин, burst 30) үйлчилнэ.

Хэрэглэгч үүсэх: амжилттай дуусахад иргэнийг civil_id-ээр түлхүүрлэн upsert хийнэ (нийтийн RP нь national_id биш civil_id авдаг). Шинэ хэрэглэгчийн default role нь user.

2. Google холболт

pkg/google, GOOGLE_* тохиргоо. Товч нь креденшл тохируулагдсан үед л харагдана.

Endpoint Юу
POST /api/v1/auth/google Code-ийг exchange хийж, eID хэрэглэгчид холбогдсон Google данснаас нэвтрүүлнэ (эсвэл холбоно)
DELETE /api/v1/auth/google/link Холбоосыг салгана

3. Session-ийн амьдралын мөчлөг

Нэвтрэх аргаас үл хамааран session нь JWT access + refresh хос:

Endpoint Юу
POST /api/v1/auth/refresh Токен хосыг сэлгэнэ (rotation)
POST /api/v1/auth/logout Refresh токеныг хүчингүй болгоно

Хамгаалалтууд:

  • kind claim guard — refresh токеныг access токен болгон ашиглах боломжгүй.
  • User.TokensRevokedBefore cutoff — креденшл солигдсоны өмнөх бүх токен татгалзагдана.
  • Logout нь refresh-ийг цуцлаад access-ийг deny-list-д оруулна (Redis).
  • JWT_SECRET эсвэл JWT_ISSUER солих нь бүх session-ийг хүчингүй болгоно.

RSC дотроос refresh дуудахгүй

Refresh нь токеныг эргүүлдэг тул cookie бичих боломжгүй контекстээс дуудвал session алдагдана. lib/api.ts-ийн tryRefresh эхлээд cookie бичигдэх боломжтойг шалгадаг.

4. Super admin — тусдаа урсгал

Super admin нь энгийн админаас тусдаа хүснэгтэд (superadmin_accounts) амьдардаг. Тиймээс нэг хүн eID-ээр админ, Google-ээр super admin байж чадна.

Onboarding нь олон алхамт wizard (/superadmin/onboard):

урилгын allow-list  →  Google  →  eID  →  и-мэйл OTP  →  TOTP + сэргээх код
Endpoint Алхам
POST /v1/auth/superadmin/onboard/google Google баталгаажуулалт
POST /v1/auth/superadmin/onboard/eid/{start,start-id,poll} eID баталгаажуулалт
POST /v1/auth/superadmin/onboard/email/{send,verify} И-мэйл OTP
POST /v1/auth/superadmin/onboard/totp/{init,verify} TOTP тохируулах + сэргээх код
POST /v1/auth/superadmin/mfa Дараагийн нэвтрэлт бүрд MFA

TOTP secret болон сэргээх кодууд нь INTEGRATION_ENC_KEY-ээр шифрлэгдэнэ.

INTEGRATION_ENC_KEY-г хэзээ ч бүү соль

Энэ түлхүүрээр super admin-ийн TOTP secret ба интеграцын OAuth токенууд шифрлэгдсэн. Солибол бүгд эвдэрнэ — сэргээх арга байхгүй.

Эхний super admin-ыг SUPERADMIN_EMAIL (эсвэл DB)-ээс bootstrap хийнэ, API-аар хэзээ ч биш.

5. Нэвтрэлтийн хамгаалалт

Хамгаалалт Утга
Rate limit /v1/auth/* ~5/мин, per-IP
Body cap 4 KiB
Lockout Амжилтгүй оролдлогыг login_events-д бүртгэж түгжинэ
Security event Сэжигтэй үйлдлийг security_events-д бичнэ
Audit Мутаци бүр hash-chain audit log-д

Цааш нь