Refresh Token Rotation Auth0 : sécurité maximale pour les sessions longues

La Refresh Token Rotation détecte automatiquement le vol de tokens. Configuration, comportement en cas de vol détecté, et stratégies pour les applications mobiles et SPAs.

Par Auth0.Expert · 2025-04-10 · 8 min de lecture

Refresh Token Sécurité Sessions

Refresh Token Rotation Auth0 : guide complet

TL;DR

La Refresh Token Rotation émet un nouveau refresh token à chaque utilisation et invalide l'ancien. Si l'ancien est réutilisé (vol détecté), Auth0 révoque toute la famille de tokens — déconnectant l'attaquant et l'utilisateur légitime simultanément.

---

Comment fonctionne la rotation

Voici un exemple de scénario d'utilisation et d'attaque de la rotation des refresh tokens.

1. Login initial → { access_token (15min), refresh_token_1 }

2. AT expire → POST /token { refresh_token_1 }
   → { access_token (15min), refresh_token_2 }  // refresh_token_1 révoqué

3. Attaquant vole refresh_token_1 et tente de l'utiliser
   → Auth0 détecte la réutilisation → RÉVOQUE toute la famille
   → refresh_token_2 aussi révoqué
   → L'utilisateur est déconnecté (doit re-login)

Ce bloc illustre la logique de rotation, la détection du vol de token, et la révocation en cascade.

---

Configuration dans Auth0

Vous pouvez activer la rotation côté dashboard avec ces paramètres, qui contrôlent la sécurité et la durée de vie des tokens.

{
  "rotation_type": "rotating",
  "expiration_type": "expiring",
  "token_lifetime": 2592000,         // 30 jours
  "infinite_token_lifetime": false,
  "idle_token_lifetime": 1296000,    // 15 jours d'inactivité
  "infinite_idle_token_lifetime": false,
  "leeway": 3                        // 3 secondes de tolérance race condition
}

---

Implémentation côté client

Voici comment intégrer la Refresh Token Rotation côté application, en assurant la sécurité locale des tokens.

React Native (mobile)

Ce code montre comment stocker localement et rafraîchir un refresh token de manière sécurisée sur une app mobile.

import * as SecureStore from 'expo-secure-store';

// Stocker le refresh token de façon sécurisée
async function saveRefreshToken(token: string) {
  await SecureStore.setItemAsync('refresh_token', token, {
    keychainAccessible: SecureStore.WHEN_UNLOCKED,
  });
}

// Rafraîchir le token
async function refreshAccessToken(): Promise<string> {
  const refreshToken = await SecureStore.getItemAsync('refresh_token');
  if (!refreshToken) throw new Error('Pas de refresh token');

  const response = await fetch(`https://YOUR_DOMAIN.auth0.com/oauth/token`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      grant_type: 'refresh_token',
      client_id: CLIENT_ID,
      refresh_token: refreshToken,
    }),
  });

  const data = await response.json();

  if (!response.ok) {
    // Token révoqué → forcer re-login
    await SecureStore.deleteItemAsync('refresh_token');
    throw new Error('Session expirée');
  }

  // Sauvegarder le NOUVEAU refresh token
  await saveRefreshToken(data.refresh_token);
  return data.access_token;
}

Ce script gère le stockage sécurisé, la requête de rafraîchissement, la gestion d’erreur et la rotation du refresh token.

SPA avec auth0-react

Dans une SPA, Auth0 React gère la rotation automatiquement — il suffit d’activer useRefreshTokens.

// auth0-react gère la rotation automatiquement
// Assurez-vous que useRefreshTokens est activé
<Auth0Provider
  domain="login.yourapp.com"
  clientId="CLIENT_ID"
  useRefreshTokens={true}
  cacheLocation="localstorage"
  authorizationParams={{
    scope: 'openid email offline_access', // offline_access requis !
  }}
>

---

Race condition et leeway

Voici comment on gère le risque qu'un refresh token soit utilisé presque simultanément dans deux contextes, par exemple plusieurs onglets ouverts.

// auth0-react gère cela automatiquement avec un lock
// Pour une implémentation custom, utilisez un mutex :
import { Mutex } from 'async-mutex';

const refreshMutex = new Mutex();

async function getValidToken() {
  return refreshMutex.runExclusive(async () => {
    // Un seul refresh à la fois
    return refreshAccessToken();
  });
}

Ce code garantit qu’une seule opération de rotation de refresh token peut se produire à la fois côté client.

---

Révocation manuelle

Pour plus de contrôle, vous pouvez révoquer un refresh token manuellement via l’API Auth0.

# Révoquer un refresh token spécifique
curl -X POST "https://YOUR_DOMAIN.auth0.com/oauth/revoke"   -H "Content-Type: application/json"   -d '{
    "client_id": "CLIENT_ID",
    "client_secret": "CLIENT_SECRET",
    "token": "REFRESH_TOKEN"
  }'

---

Scénarios et comportements

Le tableau ci-dessous récapitule les réponses d’Auth0 aux cas d’usage courants lors de la rotation des tokens.

| Scénario | Comportement Auth0 | |----------|-------------------| | Token bien utilisé | Nouveau RT émis, ancien révoqué | | Token expiré (lifetime) | Erreur invalid_grant → re-login | | Token inactif (idle) | Erreur invalid_grant → re-login | | Réutilisation détectée | Famille entière révoquée | | Révocation manuelle | Token invalide immédiatement |

---

> 🔐 Audit de sécurité des sessions : nos experts analysent votre stratégie de gestion des tokens et identifient les vulnérabilités dans votre implémentation actuelle.

📞 +33 1 23 45 67 89 · 📧 [email protected]


Autres articles