Authorization Code Flow s PKCE
PKCE (Proof Key for Code Exchange) je bezpečnostní rozšíření navržené pro public klienty, kteří nemohou bezpečně ukládat client secret. PKCE je vyžadováno pro všechny public klienty (SPA, mobilní aplikace).
Jak PKCE funguje
PKCE přidává další vrstvu zabezpečení pomocí dynamicky generovaného tajemství:
- Code Verifier: Náhodný řetězec (43-128 znaků) vygenerovaný vaší aplikací
- Code Challenge: SHA256 hash code verifieru, odeslaný s autorizačním požadavkem
- Ověření: Token endpoint ověří, že code verifier odpovídá původnímu challenge
To zabraňuje útokům typu authorization code interception, protože útočník by potřeboval code verifier k výměně kódu za tokeny.
Krok 1: Vygenerování Code Verifier a Challenge
Code verifier musí být kryptograficky náhodný řetězec používající znaky: A-Z, a-z, 0-9, -, ., _, ~
JavaScript příklad:
// Vygenerování code verifier (43-128 znaků)
function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return base64URLEncode(array);
}
// Vygenerování code challenge (SHA256 hash verifieru)
async function generateCodeChallenge(verifier) {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const hash = await crypto.subtle.digest('SHA-256', data);
return base64URLEncode(new Uint8Array(hash));
}
// Base64 URL kódování (bez paddingu)
function base64URLEncode(buffer) {
return btoa(String.fromCharCode(...buffer))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
// Použití
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
// Bezpečně uložte codeVerifier (sessionStorage) pro pozdější použití
sessionStorage.setItem('code_verifier', codeVerifier);
Příklady hodnot:
Code Verifier: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
Code Challenge: E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
Krok 2: Sestavení autorizační URL s PKCE
Přidejte PKCE parametry ke standardnímu autorizačnímu požadavku:
https://your-sso-domain.com/connect/authorize?\
client_id=my-spa-app&\
redirect_uri=https%3A%2F%2Fmyapp.com%2Fcallback&\
response_type=code&\
scope=openid%20profile%20email&\
state=abc123xyz&\
code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&\
code_challenge_method=S256
Dodatečné PKCE parametry:
| Parametr | Povinný | Popis |
|---|---|---|
code_challenge | Ano | SHA256 hash code verifieru (base64url kódovaný) |
code_challenge_method | Ano | Musí být S256 (SHA256) nebo plain (nedoporučeno) |
Krok 3: Výměna kódu za tokeny
Při výměně kódu zahrňte původní code verifier (NE challenge):
curl -X POST https://your-sso-domain.com/connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=my-spa-app" \
-d "code=SplxlOBeZQQYbYS6WxSbIA" \
-d "redirect_uri=https://myapp.com/callback" \
-d "code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
Pro public klienty není vyžadován žádný client_secret. code_verifier dokazuje vlastnictví autorizačního požadavku.
Parametry token požadavku (PKCE):
| Parametr | Povinný | Popis |
|---|---|---|
grant_type | Ano | Musí být authorization_code |
client_id | Ano | Client ID vaší aplikace |
code | Ano | Authorization code z callbacku |
redirect_uri | Ano | Musí přesně odpovídat původnímu požadavku |
code_verifier | Ano | Původní code verifier (NE challenge) |
Běžné PKCE chyby
| Chyba | Příčina | Řešení |
|---|---|---|
invalid_grant se zprávou "code_verifier" | Code verifier neodpovídá challenge | Ujistěte se, že používáte stejný verifier, který byl použit k vygenerování challenge |
invalid_request | Chybí code_challenge nebo code_verifier | Zahrňte oba parametry v příslušných požadavcích |
| Challenge method not supported | Použití nepodporované metody | Použijte S256 (doporučeno) |