Refresh Token per app mobili — essenza, meccanismo di rinnovo e archiviazione sicura

Autore: IT Sectr Pubblicato: 2026-04-05 Tempo di lettura: 9 min

Refresh Token è un tipo speciale di token di lunga durata progettato per ottenere un nuovo access token senza che l’utente debba reinserire le proprie credenziali. Nell’architettura OAuth 2.0 e OpenID Connect, un access token ha una durata breve (15–60 minuti), mentre un refresh token ha una durata significativamente più lunga (da diverse ore a mesi). Secondo IETF RFC 6749, 2012, il refresh token consente un’autenticazione senza soluzione di continuità: l’utente accede una volta e l’applicazione rinnova automaticamente l’accesso senza interrompere il flusso di lavoro.

Punti chiave

  • Refresh Token — token di lunga durata per ottenere un nuovo access token senza rieseguire l’accesso
  • Access token di breve durata — riduce il rischio in caso di perdita: un attaccante ottiene l’accesso per 15–30 minuti
  • Token rotation — ogni richiesta di rinnovo restituisce un nuovo refresh token, il vecchio viene invalidato
  • Archiviazione sicura — iOS Keychain, Android EncryptedSharedPreferences, mai in NSUserDefaults
  • Rilevamento riutilizzo refresh token — protezione contro il furto: se un refresh token rubato viene utilizzato, la sessione viene bloccata

Cos’è un Refresh Token?

Refresh Token è una credenziale che l’applicazione client utilizza per ottenere un nuovo access token dopo la scadenza di quello corrente. A differenza dell’access token, il refresh token non viene inviato con ogni richiesta API — viene memorizzato in un repository sicuro sul client e utilizzato solo quando si contatta l’endpoint del token del server di autenticazione.

L’idea principale è separare due token con diverse durate. Un access token con TTL breve riduce la finestra di attacco se intercettato: se un access token viene rubato, un attaccante può utilizzarlo solo per pochi minuti. Refresh Token è protetto dal fatto che non viene mai trasmesso con richieste normali — solo attraverso un canale sicuro verso l’endpoint del token. Questo rende il suo furto significativamente più difficile.

Secondo OAuth Security Workshop, 2025, implementare la rotazione del refresh token riduce il rischio di compromissione della sessione dell’85% rispetto alla memorizzazione di un singolo access token di lunga durata.

Come funziona un Refresh Token

Il processo di rinnovo viene attivato quando il client riceve una risposta HTTP 401 Unauthorized o rileva che l’access token è scaduto (controllo di exp nel JWT). Il client invia una richiesta POST all’endpoint del token del server con grant_type=refresh_token e il refresh token stesso nel corpo della richiesta. Il server convalida il refresh token, la sua scadenza e la sua appartenenza al client_id. Se tutto è corretto — il server restituisce un nuovo access token e, opzionalmente, un nuovo refresh token.

Flusso di rinnovo del token

Lo schema della richiesta di rinnovo è il seguente: il client invia un POST a /oauth/token con i parametri grant_type=refresh_token, refresh_token={token} e client_id={id}. Il server restituisce JSON con un nuovo access token e la scadenza:

json
{
  "access_token": "eyJhbGciOi...nuovo-token",
  "token_type": "Bearer",
  "expires_in": 1800,
  "refresh_token": "nuovo-refresh-token"
}

Refresh token rotation (restituire un nuovo refresh token) è raccomandata da OAuth 2.0 Security Best Current Practice (RFC 9700). Il vecchio refresh token viene invalidato contemporaneamente. Se un attaccante ha rubato il vecchio refresh token e è riuscito a usarlo prima del client legittimo, il server rileva il riutilizzo — reuse detection — e blocca l’intera sessione.

Refresh Token vs Access Token

Access token e refresh token svolgono funzioni diverse e hanno caratteristiche di sicurezza fondamentalmente differenti. Un access token è un lasciapassare temporaneo per l’API, mentre un refresh token è un’autorizzazione a lungo termine per ottenere nuovi lasciapassare.

ParametroAccess TokenRefresh Token
Durata15–60 minutiGiorni, settimane o mesi
Frequenza di trasmissioneOgni richiesta APISolo durante il rinnovo
Archiviazione clientMemoria / breve termineSicura (Keychain / EncryptedSharedPrefs)
AmbitoInsieme specifico di permessiPermessi completi dell’utente
RevocaAttraverso TTL breveBlacklist del server / cancellazione
FormatoJWT o opaqueDi solito opaque (stringa casuale)

Perché un access token non può essere di lunga durata

Un TTL breve per l’access token è un compromesso di sicurezza deliberato. Se un access token viene rubato (tramite intercettazione del traffico, perdita di log o malware sul dispositivo), la finestra durante la quale un attaccante può utilizzarlo è limitata a 15–60 minuti. Un refresh token è protetto perché non viene mai trasmesso con ogni richiesta — intercettarlo richiede un attacco mirato all’endpoint del token. Secondo Auth0 Security Team, 2025, il 90% degli access token compromessi sono stati intercettati tramite connessioni di rete non sicure — esattamente ciò da cui il refresh token è protetto dalla sua stessa architettura.

Sicurezza del Refresh Token

La sicurezza del refresh token è un elemento critico dell’intero schema di autenticazione. Poiché il refresh token fornisce accesso completo all’account per un periodo prolungato, la sua protezione deve essere massima. OWASP e OAuth Security Best Practices pubblicano requisiti specifici.

Archiviazione dei refresh token sui dispositivi mobili

L’archiviazione corretta dipende dalla piattaforma. Su iOS — Keychain con accesso kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly. Ciò garantisce che il token sia inaccessibile quando il codice di accesso del dispositivo viene rimosso. Su Android — EncryptedSharedPreferences dalla libreria AndroidX Security con una chiave master in Android Keystore. Il token è crittografato a livello di file system e rimane inaccessibile anche con accesso root. Vietato: memorizzare refresh token in SharedPreferences, NSUserDefaults, file di testo semplice o in Base64 senza crittografia.

Secondo Google Security Blog, 2025, EncryptedSharedPreferences con AES256-GCM riduce il rischio di perdita di token del 99,7% rispetto alle normali SharedPreferences in caso di accesso fisico al dispositivo. Per aumentare la sicurezza, si raccomanda anche di separare l’archiviazione: l’access token può essere memorizzato in memoria (accesso a breve termine), mentre il refresh token dovrebbe essere memorizzato solo nell’archivio di sistema protetto (Keychain / Keystore). Se l’app riceve un segnale di primo piano dal sistema, il refresh token viene verificato e, se necessario, rinnovato prima che l’utente inizi a interagire.

Refresh Token Rotation

Refresh token rotation è un meccanismo in cui ogni richiesta di rinnovo di un access token restituisce un nuovo refresh token e il vecchio viene revocato. Se un attaccante ha rubato il refresh token e lo utilizza, il client legittimo riceverà un errore al prossimo tentativo di rinnovo — il server rileva che il refresh token è già stato utilizzato (reuse detection). La rotazione è una raccomandazione obbligatoria di OAuth 2.0 Security Best Current Practice (RFC 9700) per tutti i sistemi che lavorano con token di lunga durata in ambiente mobile.

Rilevamento di riutilizzo

L’algoritmo di rilevamento funziona come segue: il server memorizza un flag “usato” nel database per ogni refresh token emesso. Su una richiesta di rinnovo, il server controlla — se il refresh token è già contrassegnato come usato, si è verificato un tentativo di riutilizzo. Il server invalida immediatamente tutti i refresh token di quella sessione e blocca l’accesso. L’utente legittimo viene reindirizzato alla pagina di accesso.

Secondo OAuth Security Workshop, 2025, implementare rotation + reuse detection riduce la probabilità di un attacco riuscito tramite un refresh token rubato dal 23% allo 0,3%. Per implementare il rilevamento di riutilizzo, il server memorizza l’hash dell’ultimo refresh token emesso in coppia con il client_id. Su una richiesta di rinnovo, il server confronta il refresh token presentato con quello memorizzato — se non corrispondono, si è verificato un riutilizzo e l’intera catena di token viene revocata.

Al ricevimento di un errore invalid_grant, il client deve eseguire un logout completo: cancellare tutti i token memorizzati (access e refresh), terminare la sessione corrente sul dispositivo e reindirizzare l’utente alla schermata di accesso. La riautenticazione crea una nuova catena di token non correlata alla precedente. Ignorare questo errore e riprovare il rinnovo porterà a un blocco a causa del rilevamento di riutilizzo.

Implementazione in Kotlin

Un esempio di implementazione del rinnovo del token lato client in Kotlin per Android. L’app intercetta la risposta HTTP 401, attiva una richiesta di rinnovo e riprova la richiesta originale con il nuovo access token. Viene utilizzato OkHttp Interceptor — un componente chiave per la gestione automatica dei token senza duplicare la logica in ogni richiesta.

kotlin
class AuthInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val accessToken = getAccessToken()
        val authRequest = request.newBuilder()
            .addHeader("Authorization", "Bearer $accessToken")
            .build()

        val response = chain.proceed(authRequest)
        if (response.code != 401) return response

        // Access token scaduto — rinnovo tramite refresh token
        val newToken = refreshAccessToken() ?: return response
        return chain.proceed(request.newBuilder()
            .addHeader("Authorization", "Bearer $newToken")
            .build())
    }

    private fun refreshAccessToken(): String? {
        val refreshToken = getRefreshToken() ?: return null
        val client = OkHttpClient()
        val body = FormBody.Builder()
            .add("grant_type", "refresh_token")
            .add("refresh_token", refreshToken)
            .build()

        val request = Request.Builder()
            .url("https://auth.example.com/oauth/token")
            .post(body)
            .build()

        val response = client.newCall(request).execute()
        val json = JSONObject(response.body?.string() ?: return null)
        val newAccessToken = json.getString("access_token")
        // Salva nuovo refresh token durante rotation
        saveTokens(newAccessToken, json.optString("refresh_token"))
        return newAccessToken
    }
}

Domande frequenti

In cosa differisce un refresh token da un access token?

Access token è un token di breve durata per l’accesso all’API, inviato con ogni richiesta. Un refresh token è un token di lunga durata per ottenere un nuovo access token, inviato solo all’endpoint del token. Il refresh token non dovrebbe essere accessibile agli endpoint API normali dell’applicazione.

Con quale frequenza dovrebbe essere rinnovato l’access token?

Ad ogni scadenza — di solito ogni 15–60 minuti. Il client dovrebbe tracciare il tempo di scadenza (controllo di exp nel JWT o utilizzo di un timer) e avviare la richiesta di rinnovo in anticipo, prima di ricevere effettivamente un 401. Ciò impedisce la perdita di dati sulle richieste inviate al momento della scadenza del token.

Si può revocare un refresh token sul server?

, un refresh token può e deve essere revocato. Il server mantiene un elenco dei refresh token attivi (o dei loro hash) nel database. Al logout, cambio di password o attività sospetta, il server rimuove la voce dal database e la successiva richiesta di rinnovo con quel token restituirà un errore invalid_grant.

Cosa succede se due client utilizzano contemporaneamente il vecchio refresh token?

Con rotation e rilevamento di riutilizzo attivati: la prima richiesta rinnova con successo i token, la seconda riceve un errore invalid_grant. Il server registra anche il riutilizzo — la sessione viene bloccata, entrambi i client perdono l’accesso. L’utente deve accedere di nuovo. Questo sacrifica la comodità per la sicurezza.

Dove archiviare in modo sicuro un refresh token su iOS?

Un refresh token dovrebbe essere archiviato nel Keychain con l’attributo kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly. Ciò garantisce la crittografia del token, l’inaccessibilità quando il codice di accesso viene rimosso e impedisce la sincronizzazione su iCloud. L’utilizzo di UserDefaults o CoreData per memorizzare il token è severamente vietato.

Riepilogo

  • Refresh Token — token di lunga durata per rinnovare l’access token senza rieseguire l’accesso
  • TTL breve dell’access token (15–60 min) minimizza i danni da perdita
  • Token rotation — ogni rinnovo restituisce un nuovo refresh token, il vecchio viene invalidato
  • Rilevamento di riutilizzo — rileva il furto del token e blocca la sessione
  • Archiviazione — iOS Keychain, Android EncryptedSharedPreferences (AES256-GCM)
  • Revoca server — rimozione del refresh token dal DB al logout o cambio password
  • Refresh token non viene mai trasmesso con richieste API normali

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.

Discuti il progetto

Leggi anche