Flussi OAuth e token
Questa pagina è la guida tecnica per implementare il flusso OAuth nella tua applicazione. Spiega cosa succede "sotto il cofano" quando la tua app accede ai dati delle cliniche tramite le API GipoNext.
💡 Prerequisiti
Prima di leggere questa pagina, assicurati di aver compreso:
- Il modello a due identità (applicazione + utente) — spiegato nella sezione seguente
- Registrare l'applicazione — come ottenere
client_ideclient_secret
💡 Nota sull'implementazione
Ti consigliamo di usare librerie OAuth 2.0 già collaudate per il tuo linguaggio o framework (es. IdentityModel per .NET, passport-oauth2 per Node.js, requests-oauthlib per Python). Scrivere il flusso OAuth da zero espone a rischi gravi se si commettono errori.
Credenziali sviluppatore e credenziali di accesso al sistema
OAuth 2.0 è lo standard che permette alla tua applicazione di accedere alle API per conto di un utente, senza che tu debba gestire le sue credenziali. L'utente fa login su account.gipo.it, autorizza la tua app e il sistema rilascia un access token che usi per chiamare le API.
Quando si parla di autenticazione tramite OAuth, è facile pensare che basti fare il login con le proprie credenziali. In realtà sono due i protagonisti coinvolti in ogni autenticazione, e capire la distinzione tra di loro è fondamentale per integrare correttamente le API GipoNext.
💡 In sintesi
Ogni autenticazione OAuth richiede due identità distinte:
- L'applicazione — chi sta facendo la richiesta (identificata da un
client_idunivoco). - L'utente — la persona che fa il login in modo interattivo.
Entrambe devono essere presenti e valide. Non basta una sola delle due.
Tabella riepilogativa: applicazione vs. utente
| Applicazione | Utente | |
|---|---|---|
| Cosa identifica | Il software che chiama le API | La persona che usa il software |
| Come si crea | Registrazione su account.gipo.it dal pannello Developer | Registrazione su giponext.it o attivazione da parte della clinica |
| Chi approva | Gipo (amministratore) | Automatico (o attivazione da clinica) |
| Credenziali | client_id + client_secret | Username + password |
| Quando vengono usate | Ad ogni richiesta di token (in background) | Solo durante il login interattivo |
| Cosa determina | Quali scope/permessi sono configurati per l'app | A quale tenant/clinica accedere |
| Può essere revocata | Sì, dall'amministratore Gipo | Sì, dall'utente o dall'admin della clinica |
| Che mail usare | Mailing list, gruppo di lavoro | Mail personale |
Dettagli su come registrare un'applicazione sono nella pagina dedicata alla registrazione dell'applicazione.
Il flusso OAuth passo per passo
Il flusso presuppone che tu abbia già registrato la tua applicazione e ottenuto client_id e client_secret. Il tipo di applicazione che hai scelto in fase di registrazione determina quale flusso usare:
| Tipo di app | Flusso consigliato |
|---|---|
| Web server (PHP, .NET, Java, Python...) | Authorization Code |
| App desktop o mobile | Authorization Code (con PKCE se nativa) |
| Dispositivo senza browser (stampante, CLI, TV...) | Device Code |
1. Ottieni un access token dal server di autorizzazione
Prima che la tua applicazione possa accedere ai dati, deve ottenere un access token dal server di autorizzazione di GipoNext (account.gipo.it).
L'access token concede accesso a un insieme di risorse controllato dagli scope che hai richiesto. Ogni scope abilita un gruppo di endpoint specifico (pazienti, agende, referti, fatture…).
Durante questo passo:
- La tua app avvia il flusso OAuth inviando una richiesta con
client_id,scopee altri parametri. - L'utente viene reindirizzato su
account.gipo.itdove fa login e vede la schermata di consenso — cioè l'elenco di permessi che la tua app sta richiedendo. - Se l'utente accetta, il server rilascia un codice di autorizzazione (o direttamente il token, nel Device Code flow).
- La tua app scambia il codice con il token endpoint per ottenere l'access token.
⚠️ Il consenso dell'utente è esplicito
L'utente vede chiaramente il nome della tua applicazione e la lista degli scope richiesti. Non è possibile ottenere un access token senza che l'utente abbia deliberatamente concesso l'accesso.
2. Verifica gli scope concessi dall'utente
Dopo aver ricevuto l'access token, confronta gli scope presenti nella risposta con quelli di cui la tua app ha bisogno. Se l'utente ha concesso un sottoinsieme di scope (ad esempio ha accettato giponext.patients ma non giponext.invoices), le funzionalità della tua app che richiedono la fatturazione non saranno disponibili.
Gestisci questo caso in modo elegante: disabilita le funzionalità non coperte, oppure guida l'utente a concedere i permessi mancanti.
💡 Best practice: scope incrementali
Richiedi gli scope nel momento in cui servono, non tutti in anticipo. Ad esempio, richiedi giponext.invoices solo quando l'utente accede alla sezione fatturazione della tua app. Gli utenti tendono ad accettare più volentieri permessi richiesti nel contesto giusto.
3. Invia l'access token alle API
Includi l'access token in ogni chiamata HTTP alle API GipoNext usando l'header Authorization:
GET https://api.giponext.it/v2/tenants/{tenantId}/patients
Authorization: Bearer <access_token>
Accept: application/json⚠️ Non passare il token come parametro URL
Evita di inviare il token come query string (?access_token=...): i parametri URL possono finire in log di sistema, proxy e browser history non protetti.
L'access token è valido solo per gli scope richiesti. Un token con scope giponext.patients non può chiamare endpoint di fatturazione o referti.
4. Rinnova l'access token quando scade
Gli access token hanno una durata limitata (in genere da alcune ore a qualche giorno, a seconda della configurazione). Quando scadono, le chiamate API restituiscono 401 Unauthorized.
Se hai richiesto lo scope offline_access, hai ricevuto anche un refresh token. Con esso puoi ottenere un nuovo access token senza chiedere all'utente di fare di nuovo il login:
POST https://account.gipo.it/connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token=<refresh_token>
&client_id=<client_id>
&client_secret=<client_secret>Se anche il refresh token è scaduto (o è stato revocato), l'utente dovrà fare di nuovo il login. Vedi la sezione Scadenza del refresh token più sotto.
Scenari per tipo di applicazione
Applicazioni web server
Per app con backend (PHP, .NET, Java, Python, Node.js, Ruby…) che possono aprire un browser e gestire redirect.
La sequenza di autorizzazione inizia quando il tuo backend reindirizza il browser dell'utente su account.gipo.it/connect/authorize con i parametri richiesti. Dopo il login e il consenso, il server reindirizza alla tua redirect_uri con un code. Il tuo backend scambia il code con il token endpoint e ottiene access_token e refresh_token.
Parametri chiave della richiesta a /connect/authorize:
| Parametro | Valore |
|---|---|
response_type | code |
client_id | Il tuo client_id |
redirect_uri | URL della tua app (deve coincidere con quello registrato) |
scope | Scope separati da spazio (es. openid offline_access giponext.patients) |
state | Valore casuale per prevenire CSRF (verifica che torni uguale) |
Salva il refresh_token in modo sicuro e usa l'access_token per le chiamate API. Quando l'access token scade, usa il refresh token per ottenerne uno nuovo senza chiedere di nuovo il login.
Applicazioni installate (desktop o mobile)
Per app native su Windows, macOS, Linux, Android o iOS che possono aprire un browser di sistema.
Il flusso è identico all'Authorization Code, con una differenza: le app native non possono tenere un client_secret davvero segreto (il codice è sul dispositivo dell'utente). In questo caso, usa PKCE (Proof Key for Code Exchange) al posto del client secret, oppure verifica con Gipo quale configurazione è supportata per la tua tipologia di app.
Dispositivi con input limitato (Device Code)
Per dispositivi senza browser, CLI, strumenti di integrazione batch o ambienti server dove non è possibile aprire una finestra di login interattiva.
L'utente autorizza da un altro dispositivo (PC o smartphone), mentre il dispositivo principale fa polling in attesa del token.
Errori di polling da gestire:
| Errore | Significato |
|---|---|
authorization_pending | L'utente non ha ancora autorizzato — riprova dopo interval secondi |
slow_down | Polling troppo frequente — aumenta l'intervallo di attesa |
expired_token | Il device_code è scaduto — ricomincia dal passo 1 |
access_denied | L'utente ha rifiutato — interrompi il polling e informa l'utente |
Anche il refresh token si rinnova
Il refresh token ha una finestra di validità mobile: se viene usato regolarmente per richiedere nuovi access token, continua a rinnovarsi senza intervento umano.
Se invece resta inutilizzato fino alla scadenza, sarà necessaria una nuova autenticazione interattiva.
Servizi in background (Windows Service, Daemon Unix, etc.)
Per le applicazioni che agiscono in background, ma hanno capacità di logging, puoi usare il flusso Device Code: all'avvio il servizio avvia il flusso e scrive il code in un punto visibile a un operatore, che completa l'autenticazione da un altro dispositivo.
In alternativa puoi creare una piccola applicazione separata dal tuo servizio in background, con il solo scopo di gestire l'autenticazione interattiva. Questa applicazione salva access_token e refresh_token in uno storage sicuro condiviso con il servizio, che poi può chiamare le API senza richiedere nuovi interventi all'utente finale.
Rinnovo periodico automatico
Per le applicazioni che implementano scheduler o job pianificati, è indispensabile configurare il refresh periodico del token di autenticazione. Tale operazione deve essere schedulata con una frequenza tale da garantire il rinnovo dei token prima della loro naturale scadenza, assicurando così la continuità operativa dei processi automatizzati.
Dimensioni e durata dei token
| Token | Durata tipica | Note |
|---|---|---|
| Access token | Ore / giorni | Va incluso in ogni chiamata API. Quando scade, le API rispondono 401. |
| Refresh token | Settimane / mesi | Serve per rinnovare l'access token. Va conservato in modo sicuro. |
| Authorization code | Pochi minuti | Monouso. Va scambiato immediatamente con il token endpoint. |
⚠️ Conserva i token in modo sicuro
- Non salvare mai l'access token o il refresh token in
localStoragedel browser (accessibile da JavaScript). - Usa storage sicuri: cookie
HttpOnly+Secure, Keychain (iOS/macOS), Credential Manager (Windows), oppure variabili d'ambiente o vault per i backend.
Scadenza del refresh token
Scrivi sempre il codice aspettandoti che un refresh token possa smettere di funzionare. Un refresh token può diventare non valido per uno dei seguenti motivi:
- L'utente ha revocato l'accesso alla tua app dal proprio profilo su account.gipo.it.
- Il token non è stato usato per un periodo prolungato (rotazione per inattività).
- L'account utente è stato disabilitato o il suo ruolo modificato dall'amministratore della clinica.
- Hai raggiunto il limite di token attivi per la stessa combinazione client + utente.
- Il client OAuth è stato revocato da un amministratore Gipo.
Quando il refresh token è scaduto o revocato, il token endpoint risponde con:
{
"error": "invalid_grant",
"error_description": "refresh token is expired"
}In questo caso non puoi rinnovare: l'utente deve fare di nuovo il login completo (flusso Authorization Code o Device Code). Gestisci questo caso nel tuo codice reindirizzando l'utente al flusso di autorizzazione.
Gli scope: cosa controlla ogni token
Ogni access token è valido solo per gli scope che l'utente ha concesso. Richiedere uno scope non significa averlo automaticamente: è l'utente che decide cosa autorizzare.
| Scope | Cosa abilita |
|---|---|
openid | Flusso OpenID Connect base (obbligatorio) |
offline_access | Rilascio del refresh token |
giponext.patients | Pazienti (anagrafica, lettura/scrittura) |
giponext.agenda | Agende e appuntamenti |
giponext.treatments | Prestazioni e prodotti |
giponext.episodes | Episodi clinici |
giponext.medicalreports | Referti medici |
giponext.invoices | Fatturazione |
giponext.fhir | Endpoint FHIR |
Vedi la lista completa in Scope e autenticazione.
Endpoint di riferimento
| Endpoint | URL |
|---|---|
| Discovery (OpenID configuration) | https://account.gipo.it/.well-known/openid-configuration |
| Authorization | https://account.gipo.it/connect/authorize |
| Token | https://account.gipo.it/connect/token |
| UserInfo | https://api.giponext.it/v2/userinfo |
| Issuer | https://account.gipo.it |
Usa il documento di discovery per ottenere dinamicamente gli endpoint: il documento è sempre aggiornato e ti protegge da eventuali cambiamenti futuri degli URL.
Prossimi passi
- Credenziali sviluppatore e credenziali di accesso al sistema — la differenza tra client OAuth e account utente
- Registrare l'applicazione — come registrare la tua applicazione
- Scope e autenticazione — lista completa degli scope e mappa risorse