OAuth 2.0 avec PKCE
Comprendre le flux OAuth 2.0 Authorization Code avec PKCE (Proof Key for Code Exchange).
Qu'est-ce que PKCE ?
PKCE (prononcé "pixy") est une extension de sécurité à OAuth 2.0 qui protège contre les attaques par interception de code d'autorisation.
Pourquoi PKCE ?
Sans PKCE, si un attaquant intercepte le code d'autorisation, il pourrait :
- L'échanger contre des tokens
- Gagner accès aux comptes utilisateur
PKCE empêche cela en exigeant une preuve que le même client qui a initié le flux est celui qui le complète.
Comment PKCE Fonctionne
1. Générer Code Verifier & Challenge
Le client doit d'abord créer une chaîne aléatoire à haute entropie (verifier) et son hash (challenge).
- JavaScript
- Python
// 1. Générer Code Verifier (Aléatoire 43-128 caractères)
const generateRandomString = (length) => {
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
let text = '';
for (let i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
const codeVerifier = generateRandomString(64);
// 2. Générer Code Challenge (SHA-256 du verifier)
async function generateCodeChallenge(verifier) {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const digest = await window.crypto.subtle.digest('SHA-256', data);
const base64Digest = btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
return base64Digest;
}
import secrets
import hashlib
import base64
# 1. Générer Code Verifier (Aléatoire 43-128 caractères)
code_verifier = secrets.token_urlsafe(64)[:128]
# 2. Générer Code Challenge (SHA-256 du verifier)
code_challenge_hash = hashlib.sha256(code_verifier.encode('ascii')).digest()
code_challenge = base64.urlsafe_b64encode(code_challenge_hash).decode('ascii').rstrip('=')
print(f"Verifier: {code_verifier}")
print(f"Challenge: {code_challenge}")
3. Requête d'Autorisation
GET /authorize?
response_type=code
&client_id=votre-client-id
&redirect_uri=https://votreapp.com/callback
&scope=openid profile email
&state=valeur-state-aleatoire
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256
4. Échange de Token
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=code-auth-recu
&redirect_uri=https://votreapp.com/callback
&client_id=votre-client-id
&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
Le serveur vérifie que sha256(code_verifier) == code_challenge avant d'émettre des tokens.
Diagramme de Flux Complet
PKCE Côté Serveur SyAuth
SyAuth supporte aussi les sessions PKCE côté serveur pour résoudre les problèmes cross-origin dans certaines architectures.
Initialiser Session PKCE
POST /oauth/pkce/init
Content-Type: application/json
{}
Réponse :
{
"session_id": "pkce_session_xxx",
"code_challenge": "ABC123...",
"code_challenge_method": "S256"
}
Utiliser dans l'Échange de Token
POST /oauth/token
{
"grant_type": "authorization_code",
"code": "xxx",
"pkce_session_id": "pkce_session_xxx" // Au lieu de code_verifier
}
Gestion par le SDK
Le SDK SyAuth gère toute la complexité PKCE automatiquement :
import { useSyAuth } from '@syauth/nextjs';
function LoginButton() {
const { loginWithRedirect } = useSyAuth();
// Le SDK fait automatiquement :
// 1. Générer code_verifier
// 2. Calculer code_challenge
// 3. Stocker verifier dans cookie sécurisé
// 4. Inclure challenge dans requête auth
// 5. Récupérer verifier pour échange de token
return (
<button onClick={() => loginWithRedirect()}>
Se connecter
</button>
);
}
Bonnes Pratiques de Sécurité
| Pratique | Description |
|---|---|
| Utiliser méthode S256 | SHA-256 est plus sécurisé que plain |
| Stockage sécurisé verifier | Utiliser cookies HttpOnly, pas localStorage |
| Valider paramètre state | Prévenir les attaques CSRF |
| Codes auth à courte durée | Les codes expirent en 5 minutes |
Problèmes Courants
"Invalid code_verifier"
Le verifier ne correspond pas au challenge. Assurez-vous d'utiliser exactement le même verifier qui a été utilisé pour créer le challenge.
"Code already used"
Les codes d'autorisation sont à usage unique. Demandez-en un nouveau si nécessaire.
"Code expired"
Les codes d'autorisation expirent après 5 minutes. Redémarrez le flux.
Prochaines Étapes
- Gestion des Tokens - En savoir plus sur les tokens d'accès et refresh
- Bonnes Pratiques de Sécurité - Recommandations de sécurité