@develit-services/auth
v1.0.1
Published
Microsluzba pro autentizaci a autorizaci uzivatelu — registrace, prihlaseni, sprava sessions, JWT tokeny a MFA. Postavena na Cloudflare Workers s D1 databazi a Secrets Store.
Downloads
3,456
Readme
Auth Service
Microsluzba pro autentizaci a autorizaci uzivatelu — registrace, prihlaseni, sprava sessions, JWT tokeny a MFA. Postavena na Cloudflare Workers s D1 databazi a Secrets Store.
Obsah
- Architektura
- Autentizacni flow
- JWT tokeny
- Secrets Store — nastaveni JWT secrets
- MFA (TOTP)
- RPC akce
- Databazove schema
- Konfigurace
- Error Codes
Architektura
Sluzba se sklada z:
- Akce (Actions) — RPC endpointy pro registraci, prihlaseni, spravu uzivatelu a MFA
- D1 Database — Uzivatele, sessions, refresh tokeny, MFA faktory
- Secrets Store — Cloudflare Worker service binding pro ulozeni JWT secrets
- Notifications Queue — Odesilani verifikacnich emailu
- Audit Logs Queue — Logovani vsech autentizacnich udalosti
Autentizacni flow
Registrace a prihlaseni
create-user-with-email-and-password
│
▼
Vytvoreni uzivatele (hash hesla + salt)
│
├─ EMAIL_CONFIRMATION_ENABLED=true → odesle verifikacni email (OTP)
│ └─ verify-user (potvrzeni tokenu)
└─ EMAIL_CONFIRMATION_ENABLED=false → uzivatel rovnou overen
sign-in-with-email-and-password
│
▼
Validace emailu + hesla
│
├─ MFA aktivni → { requireMfa: true } → challenge-and-verify-mfa → tokeny
│
└─ MFA neaktivni → vytvoreni session + token pair
└─ { accessToken, refreshToken, user }Refresh session
refresh-session (refreshToken)
│
▼
Vyhledani aktivni session podle hash refresh tokenu
│
▼
Validace uzivatele (neni smazany/zabanovany)
│
▼
Rotace tokenu:
1. Stary refresh token oznacen jako revoked
2. Novy token pair vygenerovan (s parentId vazbou)
3. { accessToken, refreshToken }JWT tokeny
Sluzba pouziva dva typy JWT tokenu, kazdy podepsany vlastnim secretem (HS256 algoritmus, knihovna jose).
Access token
- Ucel: Autorizace API pozadavku
- Expirace: konfigurovatelna pres
JWT_ACCESS_TOKEN_EXPIRES_IN(default1h) - Secret:
AUTH_SERVICE_JWT_ACCESS_SECRET(ze Secrets Store) - Payload:
sub— ID uzivateleuser— PublicUser objekt (bez hesla a saltu)iat— cas vydaniexp— cas expiracescopes— volitelne pole{ scope, resourceId? }
Refresh token
- Ucel: Ziskani noveho token pairu bez opetovneho prihlaseni
- Expirace: konfigurovatelna pres
JWT_REFRESH_TOKEN_EXPIRES_IN(default1d) - Secret:
AUTH_SERVICE_JWT_REFRESH_SECRET(ze Secrets Store) - Payload: stejny jako access token, bez
scopes - Ulozeni: v DB se uklada SHA-256 hash tokenu (ne samotny JWT)
- Rotace: pri pouziti se stary token revokuje a vytvori se novy s
parentIdvazbou
Overeni tokenu
Akce verify-access-token overi podpis a expiraci access tokenu a vrati dekodovany payload. Pouziva jwtVerify z knihovny jose.
Secrets Store — nastaveni JWT secrets
JWT secrets jsou ulozeny v Cloudflare Secrets Store — separatni worker service (secrets-store), ktery je pripojen pres service binding jako SECRETS_STORE.
Potrebne secrety
| Secret Name | Popis |
|-------------|-------|
| AUTH_SERVICE_JWT_ACCESS_SECRET | Signing secret pro access tokeny |
| AUTH_SERVICE_JWT_REFRESH_SECRET | Signing secret pro refresh tokeny |
Jak vygenerovat JWT secrets
Secrety by mely byt dostatecne dlouhe nahodne retezce (minimalne 32 znaku). Generovani:
# Pomoci openssl (doporuceno)
openssl rand -base64 64
# Nebo pomoci Node.js
node -e "console.log(require('crypto').randomBytes(64).toString('base64'))"Vygenerujte dva ruzne secrety — jeden pro access token a druhy pro refresh token. Nikdy nepouzivejte stejny secret pro oba typy tokenu.
Jak nastavit secrety v Secrets Store
Secrety se nastavuji pres Secrets Store worker. Konkretni zpusob nastaveni zavisi na implementaci secrets-store service — typicky pres jeho RPC akce nebo Cloudflare dashboard.
Po nastaveni jsou dostupne v auth service pres:
const accessSecret = await this.env.SECRETS_STORE.get({
secretName: 'AUTH_SERVICE_JWT_ACCESS_SECRET',
})
const refreshSecret = await this.env.SECRETS_STORE.get({
secretName: 'AUTH_SERVICE_JWT_REFRESH_SECRET',
})Bezpecnostni doporuceni
- Pouzijte jiny secret pro kazde prostredi (local, dev, staging, production)
- Secrety pravidelne rotujte — pri rotaci budou existujici tokeny neplatne
- Nikdy secrety neukladejte do kodu, env souboru ani git repozitare
MFA (TOTP)
Sluzba podporuje dvoufaktorovou autentizaci pomoci TOTP (Time-based One-Time Password).
Setup flow
setup-totp-factor (userId)
│
▼
Vygenerovani TOTP secretu
│
▼
Uzivatel naskenuje QR kod v autentikacni aplikaci
│
▼
create-mfa-challenge (purpose: setup) → challengeId
│
▼
verify-mfa-challenge (challengeId + TOTP kod) → faktor overenLogin s MFA
Pokud ma uzivatel aktivni TOTP faktor, sign-in-with-email-and-password vrati { requireMfa: true }. Klient pak musi poslat totpCode v dalsim requestu, nebo pouzit challenge-and-verify-mfa.
Deaktivace MFA
Akce update-mfa-factor deaktivuje MFA faktor (status → disabled).
RPC akce
Auth service je RPC worker — nema vlastni verejne HTTP endpointy. Vsechny akce jsou dostupne pouze pres Cloudflare Worker binding.
Autentizace
| Akce | Popis |
|------|-------|
| create-user-with-email-and-password | Registrace noveho uzivatele (email + heslo) |
| sign-in-with-email-and-password | Prihlaseni — vraci token pair nebo requireMfa |
| verify-user | Overeni emailu pomoci confirmation tokenu |
| verify-access-token | Overeni platnosti access tokenu, vraci payload |
| refresh-session | Rotace token pairu pomoci refresh tokenu |
Sprava uzivatelu
| Akce | Popis |
|------|-------|
| get-auth-user | Ziskat uzivatele podle ID |
| get-auth-users | Seznam vsech uzivatelu |
| get-user-by-email | Ziskat uzivatele podle emailu |
| get-user-from-refresh-token | Ziskat uzivatele z refresh tokenu |
| update-user | Aktualizace uzivatele (metadata, email, ban) |
| update-user-password | Zmena hesla |
| delete-user | Soft delete uzivatele (+ smazani sessions) |
| delete-user-permanently | Trvale smazani uzivatele z DB |
MFA
| Akce | Popis |
|------|-------|
| setup-totp-factor | Vygenerovani TOTP secretu pro uzivatele |
| get-mfa-factor | Ziskani MFA faktoru uzivatele |
| update-mfa-factor | Deaktivace MFA faktoru |
| create-mfa-challenge | Vytvoreni MFA challenge (platnost 5 minut) |
| verify-mfa-challenge | Overeni TOTP kodu proti challenge |
| challenge-and-verify-mfa | Vytvoreni + overeni challenge v jednom kroku |
Databazove schema
user
Zakladni udaje uzivatele.
Klicove sloupce: email (unikatni), hashedPassword, salt, rawAppMetaData (JSON), rawUserMetaData (JSON), isSuperAdmin, isSsoUser, lastSignInAt, emailConfirmedAt, confirmationToken, isBanned.
session
Aktivni prihlaseni uzivatele.
Klicove sloupce: userId (FK → user), aal (Auth Assurance Level), userAgent, ip, factorId, tag, refreshedAt.
refresh_token
Evidence refresh tokenu s podporou rotace.
Klicove sloupce: userId (FK → user), sessionId (FK → session), token (SHA-256 hash), revoked (boolean), parentId (FK → refresh_token — retez rotaci).
mfa_factor
MFA faktory uzivatelu (typ totp).
mfa_challenge
MFA challenge zaznamy s casovym limitem 5 minut.
Konfigurace
Environment variables
| Promenna | Popis | Default |
|----------|-------|---------|
| JWT_ACCESS_TOKEN_EXPIRES_IN | Expirace access tokenu | 1h |
| JWT_REFRESH_TOKEN_EXPIRES_IN | Expirace refresh tokenu | 1d |
| EMAIL_CONFIRMATION_ENABLED | Zda je vyzadovano overeni emailu | — |
Service bindings
| Binding | Popis |
|---------|-------|
| SECRETS_STORE | Worker pro ulozeni JWT secrets |
| AUTH_D1 | D1 databaze |
| NOTIFICATIONS_QUEUE | Queue pro odesilani emailu |
| AUDIT_LOGS_QUEUE | Queue pro audit logy |
Error Codes
| Code | Status | Popis |
|------|--------|-------|
| InvalidCredentials | 401 | Neplatny email nebo heslo |
| Forbidden | 401 | Neplatny nebo expirovany access token |
| — | 401 | Neplatny nebo expirovany refresh token |
| — | 401 | Uzivatel je zabanovany nebo smazany |
| — | 400 | Neplatny MFA token |
| — | 400 | Challenge expirovana nebo jiz pouzita |
| — | 404 | Uzivatel nenalezen |
| — | 404 | MFA faktor nenalezen |
