Access Token — sono credenziali che l'applicazione client presenta al server per accedere a risorse API protette. Dopo l'autenticazione dell'utente, il server di autorizzazione emette un access token, che il client invia nell'intestazione HTTP Authorization con ogni richiesta. Secondo OAuth.net, 2025, un access token può essere una opaque string (stringa arbitraria senza significato semantico) o JWT (token autonomo con dati all'interno) — la scelta del formato dipende dall'architettura e dai requisiti di prestazione del sistema.
Punti chiave
Access Token — una stringa che un client (app mobile, SPA, server) utilizza per autenticare richieste HTTP a endpoint API protetti. Il token viene emesso dal server di autorizzazione dopo che l'utente ha confermato la propria identità e concesso all'applicazione le autorizzazioni appropriate (scope).
L'access token è un elemento centrale del protocollo OAuth 2.0 e di tutti i sistemi costruiti su di esso — OpenID Connect, Firebase Authentication, Auth0, Keycloak. Senza un access token, nessuna richiesta a un'API protetta verrà elaborata: il server restituisce HTTP 401 Unauthorized. Il token non identifica direttamente l'utente — conferma che il client ha il diritto di eseguire un'azione specifica per conto dell'utente (autorizzazione), non chi è l'utente (autenticazione).
Secondo Okta, 2025, più dell'80% delle API pubbliche utilizza lo schema Bearer con un access token nell'intestazione Authorization, sostituendo metodi di autenticazione obsoleti — Basic Auth e API Key. L'access token è anche la base per l'autorizzazione delegata — un modello in cui l'utente concede a un'applicazione accesso limitato ai propri dati su un altro servizio. Ad esempio, quando un'app mobile di fotoritocco richiede l'accesso a Google Drive tramite OAuth 2.0, l'utente vede una schermata di consenso con gli scope specifici e, dopo la conferma, riceve un access token con tali autorizzazioni.
Meccanismo dell'access token si basa sullo schema Bearer: il client aggiunge l'intestazione Authorization: Bearer <token> a ogni richiesta HTTP. Il server delle risorse (API) riceve il token, lo convalida e determina quali risorse sono accessibili. La convalida può avvenire in due modi: localmente (per JWT) o tramite un endpoint di introspezione (per token opachi).
Bearer token significa che chiunque presenti il token (bearer) ottiene l'accesso corrispondente. Ciò impone elevati requisiti di protezione del token durante la trasmissione e l'archiviazione. Lo schema Bearer non richiede che il client dimostri crittograficamente il possesso del token — basta trasmetterlo. Pertanto, HTTPS è obbligatorio: senza crittografia del traffico, un utente malintenzionato può intercettare il token e usarlo immediatamente.
Secondo Cloudflare, 2025, l'intercettazione di un Bearer token su una connessione HTTP non protetta avviene in media entro 12 secondi dall'invio della richiesta. L'uso di HTTPS e di un TTL breve dell'access token (15–30 minuti) riduce il rischio a praticamente zero. Protezione aggiuntiva a livello applicativo — verifica dell'origine della richiesta tramite OAuth 2.0 Token Binding (RFC 8471): il client dimostra il possesso della chiave TLS legata al token, rendendo inutile il furto del token tramite intercettazione.
Access Token esiste in due formati: opaco e JWT (autonomo). La scelta tra di essi è una delle decisioni architetturali chiave nella progettazione di un sistema di autenticazione.
| Parametro | Opaque Token | JWT |
|---|---|---|
| Formato | Stringa casuale (32–64 byte) | JSON codificato in Base64 con firma |
| Convalida | Tramite endpoint di introspezione (richiesta HTTP) | Locale (firma crittografica) |
| Contiene dati | No — solo un identificatore | Sì — claims all'interno del token |
| Revoca | Immediata — verifica lato server | Tramite blacklist o TTL breve |
| Prestazioni | Ogni richiesta → introspezione (RTT) | Verifica locale (senza RTT) |
| Dimensione | ~100 byte | ~500–2000 byte |
Opaque token è preferibile per sistemi che richiedono revoca immediata dell'accesso e verifica centralizzata dei diritti. JWT è per architetture a microservizi dove le prestazioni e la minimizzazione delle chiamate di rete sono importanti. Molti provider (Auth0, Keycloak) supportano entrambi i formati e consentono di configurare il tipo di token per ogni client. La scelta tra opaco e JWT è un compromesso tra controllo e prestazioni: opaco dà il controllo completo al server, JWT fornisce una latenza minima.
Ciclo di vita di un access token è composto da quattro fasi: emissione, trasmissione, utilizzo e scadenza. Ogni fase ha i propri requisiti di sicurezza e vincoli di protocollo.
Access Token ha una durata limitata — tipicamente 15–60 minuti. Il valore expires_in è indicato nella risposta del server di autorizzazione al momento dell'emissione del token. Dopo questo periodo, il token diventa non valido e il client deve ottenerne uno nuovo tramite il meccanismo di refresh token. Il client può verificare la scadenza in due modi: tramite il campo exp nel JWT (localmente) o tramite la risposta HTTP 401 (per token opachi).
Secondo Auth0 Best Practices, 2025, il TTL ottimale dell'access token per applicazioni mobili è di 15–30 minuti. Un TTL troppo breve (meno di 5 minuti) crea un carico eccessivo sull'endpoint del token ad ogni rinnovo — con 10.000 utenti e un TTL di 5 minuti, il server riceve fino a 2.000 richieste di rinnovo al minuto nelle ore di punta. Un TTL troppo lungo (più di 2 ore) aumenta la finestra di attacco in caso di fuga del token — un utente malintenzionato può utilizzare il token compromesso per diverse ore prima che l'accesso venga bloccato automaticamente.
Sicurezza dell'access token deve essere garantita in tutte le fasi: durante l'archiviazione sul dispositivo, durante la trasmissione sulla rete e durante l'elaborazione sul server. La raccomandazione di base è di non archiviare mai l'access token in luoghi accessibili ad altre applicazioni o processi.
Sui dispositivi mobili, l'access token viene archiviato: su iOS — nel Keychain con l'attributo kSecAttrAccessibleAfterFirstUnlock (il token è accessibile dopo il primo sblocco, anche se il dispositivo è bloccato — per gli aggiornamenti in background); su Android — in EncryptedSharedPreferences. L'access token non deve mai essere salvato in NSUserDefaults, SharedPreferences, file su memoria esterna o log dell'applicazione. Durante la trasmissione — solo HTTPS con TLS 1.3 o 1.2. Per ogni richiesta API, l'access token deve essere inviato nell'intestazione Authorization: Bearer, non nei parametri URL (query string) — gli URL finiscono nei log dei server e dei browser.
Secondo OWASP Mobile Top 10, 2025, l'archiviazione impropria dei token sul dispositivo (M1: Improper Platform Usage) e la trasmissione non sicura dei dati (M3: Insecure Communication) sono tra le tre vulnerabilità mobili più comuni che portano alla compromissione degli account. Una misura aggiuntiva — l'uso del certificate pinning per tutte le richieste con access token: il client verifica il certificato del server non solo attraverso la catena CA standard, ma anche tramite un'impronta digitale del certificato pre-salvata (SHA-256 fingerprint). Ciò previene gli attacchi man-in-the-middle anche con un CA compromesso.
Di seguito un esempio in Kotlin per Android, che dimostra l'invio di una richiesta con un access token nell'intestazione Authorization e la gestione di 401 con rinnovo automatico tramite refresh token. Viene utilizzato OkHttp con un Interceptor personalizzato.
data class TokenStore {
fun getAccessToken(): String? {
// Reading from EncryptedSharedPreferences
return encryptPrefs.getString("access_token", null)
}
fun isTokenExpired(): Boolean {
val expiresAt = encryptPrefs.getLong("expires_at", 0)
return System.currentTimeMillis() > expiresAt
}
}
class ApiClient(private val tokenStore: TokenStore) {
private val client = OkHttpClient.Builder()
.addInterceptor(AuthInterceptor(tokenStore))
.build()
fun fetchUserProfile(): UserProfile? {
val request = Request.Builder()
.url("https://api.example.com/user/profile")
.get()
.build()
val response = client.newCall(request).execute()
return if (response.isSuccessful) {
parseProfile(response.body?.string() ?: return null)
} else null
}
}
fun sendAuthenticatedRequest(token: String): Unit {
val conn = URL("https://api.example.com/data").openConnection() as HttpURLConnection
conn.setRequestProperty("Authorization", "Bearer $token")
conn.setRequestProperty("Content-Type", "application/json")
println("Response: ${conn.responseCode}")
}
L'esempio mostra due approcci: utilizzare OkHttp Interceptor per la gestione automatica dei token e l'invio diretto tramite HttpURLConnection. OkHttp Interceptor è preferibile — centralizza la logica di aggiunta e rinnovo del token, eliminando la duplicazione del codice in ogni richiesta. Tutte le richieste passano attraverso un unico interceptor che controlla lo stato della risposta e rinnova il token quando necessario senza l'intervento dello sviluppatore.
Domande frequenti
API key è un identificatore statico dell'applicazione non legato a un utente specifico. Un access token è dinamico, temporaneo e legato a un utente e a una sessione. Una API key non supporta lo scope (restrizione dei permessi), mentre un access token può avere diversi livelli di accesso per diverse operazioni.
Due modi: attivo — controllo del campo exp nel JWT (il client calcola autonomamente se il token è scaduto); passivo — invio di una richiesta e ricezione di HTTP 401 Unauthorized. Si consiglia di combinare entrambi: controllo preventivo di exp per evitare la perdita di dati e gestione del 401 come fallback.
No. Un access token non deve mai essere passato in una query string di URL. I parametri URL vengono memorizzati nella cronologia del browser, nei log del server, nel referer e nella cache dei server proxy. L'unico modo sicuro è l'intestazione Authorization: Bearer. Questo è un requisito di OAuth 2.0 Security Best Practices (RFC 9700).
Si consigliano 15–30 minuti. Viene utilizzato un refresh token con rotazione per il rinnovo automatico. Questo TTL bilancia sicurezza e UX: l'utente non nota i rinnovi e la finestra di attacco per un token divulgato è minima. Per operazioni particolarmente sensibili (trasferimenti di denaro) — 1–5 minuti.
Bearer token è un tipo di access token in cui chiunque presenti (bearer) il token ottiene l'accesso. Non è richiesta alcuna prova crittografica di possesso — basta il fatto di trasmettere il token. Lo schema Bearer è semplice ed efficace, ma richiede HTTPS per proteggere dall'intercettazione del token in transito.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche