Flusso Autenticazione: Keycloak e Token Dispositivo
L'API Gateway (api.service.js) implementa un flusso di autenticazione a 3 livelli sequenziali. Ogni richiesta con header Authorization: Bearer <token> viene validata provando in ordine: token HS256 dispositivo/operatore, token HS256 supporto, token RS256 Keycloak. Il primo livello che ha successo determina il contesto utente.
Livello 1: Token Dispositivo e Operatore (HS256)
Il primo tentativo verifica il token come JWT HS256 con issuer: 'pos-backend' e audience tra pos-cassa-ui, pos-waiter-ui, pos-stock-app.
Token Dispositivo
Emesso durante l'enrollment della licenza. Contiene:
{
"deviceId": "DEV-001",
"tenantId": "restaurant123",
"deviceName": "Cassa 1",
"licenseLevel": "premium",
"iss": "pos-backend",
"aud": "pos-cassa-ui"
}
Il contesto risultante imposta ctx.meta.user.isDevice = true e ctx.meta.tenantId per l'isolamento multi-tenant.
Token Operatore
Emesso dopo login con PIN operatore. Contiene ruolo e permessi granulari:
{
"type": "operator",
"operatorId": "OP-042",
"operatorCode": "042",
"tenantId": "restaurant123",
"role": "cassiere",
"permissions": ["discount_apply", "void_item"],
"iss": "pos-backend",
"aud": "pos-cassa-ui"
}
Il contesto imposta ctx.meta.user.isOperator = true con i permessi disponibili per i controlli di autorizzazione nei servizi downstream.
Livello 2: Token Supporto Tecnico (HS256)
Se il livello 1 fallisce, il gateway prova a validare come token di supporto con issuer: 'pos-backend-support'. Questo tipo di token e usato dai tecnici manutentori per accedere al sistema di un cliente.
Il flusso di validazione e piu rigoroso:
- Verifica firma HS256 con
SUPPORT_JWT_SECRET - Controlla che
type === 'support' - Valida la sessione di supporto (
support-access.validateSession) - Verifica il binding del dispositivo tramite header
X-Device-ID - Controlla la blacklist JTI per token revocati
Il contesto risultante imposta ctx.meta.user.isSupport = true con scope e restrictions che limitano le operazioni consentite.
Livello 3: Keycloak (RS256)
Se entrambi i livelli HS256 falliscono, il gateway tenta la validazione RS256 tramite le chiavi pubbliche JWKS di Keycloak.
Il token Keycloak contiene i claim standard OpenID Connect. Il gateway estrae il contesto dal campo groups:
{
"sub": "user-uuid",
"preferred_username": "admin@ristorante.it",
"groups": ["/tenants/T001/admins"],
"realm_access": { "roles": ["TENANT_ADMIN"] },
"iss": "https://auth.example.com/realms/pos"
}
Il metodo extractContextFromGroups analizza la gerarchia dei gruppi per derivare tenantId, resellerCode e role.
Contesto Moleculer (ctx.meta)
Indipendentemente dal livello di autenticazione, il gateway popola ctx.meta con:
| Campo | Descrizione | Esempio |
|---|---|---|
ctx.meta.user | Oggetto utente completo | { id, tenantId, roles, ... } |
ctx.meta.tenantId | ID tenant per isolamento DB | "restaurant123" |
ctx.meta.user.roles | Array ruoli per autorizzazione | ["device"], ["operator", "cassiere"] |
Tutti i servizi downstream che usano db.tenant.mixin.js estraggono ctx.meta.tenantId per selezionare il database corretto (t_restaurant123).
Endpoint Pubblici
Alcuni endpoint non richiedono autenticazione e restituiscono null come contesto utente:
/licensing/enroll,/licensing/verify,/licensing/refresh/operators/login/translations/sync/localization/languages,/localization/config
Modalita Sviluppo
Con SKIP_AUTH=true nel .env, il gateway bypassa tutta la catena di validazione e restituisce un utente di default:
{ id: "dev-user", username: "developer", tenantId: process.env.DEV_TENANT_ID || "demo" }
Questa modalita e utile per lo sviluppo locale senza un'istanza Keycloak attiva. Non deve mai essere abilitata in ambienti di produzione o staging.
FAQ
Cosa succede se il token non e valido per nessun livello?
Il gateway restituisce null, che causa una risposta HTTP 401 Unauthorized al client.
Come rinnovo un token dispositivo scaduto?
Tramite l'endpoint /licensing/refresh che emette un nuovo token senza richiedere un nuovo enrollment completo.
Posso usare contemporaneamente token dispositivo e operatore? Si. Il flusso tipico e: la postazione si autentica con il token dispositivo all'avvio, poi l'operatore fa login con PIN ottenendo un token operatore piu specifico con i suoi permessi.