Přeskočit na hlavní obsah

Rate Limits

Klubero SSO implementuje rate limiting pro zajištění stability služby a prevenci zneužití.

Tabulka Rate Limits

Všechny rate limity jsou aplikovány per IP adresa.

EndpointLimitOknoÚčel
/connect/token10 požadavků15 minutOchrana proti brute-force útokům na přihlašovací údaje
/api/twofactor/*5 požadavků5 minutOchrana proti brute-force útokům na ověřovací kódy
/api/magiclink/send3 požadavky5 minutPrevence spamu e-mailů
/connect/authorize30 požadavků1 minutaOchrana proti DoS a enumeraci redirect URI

Odpověď při překročení limitu

Když překročíte rate limit:

HTTP/1.1 429 Too Many Requests
Retry-After: 300

{
"error": "rate_limit_exceeded",
"error_description": "Too many requests. Please retry after 300 seconds.",
"retry_after": 300
}

Zpracování Rate Limits

  1. Kontrolujte status odpovědi: Hledejte HTTP 429
  2. Čtěte Retry-After header: Udává počet sekund k čekání
  3. Implementujte exponential backoff: Pro automatizované systémy
  4. Cachujte tokeny: Opakovaně používejte access tokeny dokud nevyprší

Osvědčené postupy

Dělejte

  • Cachujte a opakovaně používejte tokeny dokud nevyprší
  • Používejte refresh tokeny místo opětovné autentizace
  • Implementujte správné zpracování chyb s backoff
  • Seskupujte operace kde je to možné

Nedělejte

  • Žádat o nový token pro každé API volání
  • Znovu se autentizovat pro každou relaci
  • Okamžitě opakovat při selhání
  • Dělat mnoho sekvenčních požadavků

Příklad: Cachování tokenů

let tokenCache = {
accessToken: null,
expiresAt: null
};

async function getAccessToken() {
// Vrátit cachovaný token pokud je stále platný (s 60s rezervou)
if (tokenCache.accessToken && tokenCache.expiresAt > Date.now() + 60000) {
return tokenCache.accessToken;
}

// Požádat o nový token
const response = await fetch('/connect/token', {
method: 'POST',
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET
})
});

if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60;
throw new Error(`Rate limited. Zkuste znovu za ${retryAfter} sekund.`);
}

const data = await response.json();
tokenCache.accessToken = data.access_token;
tokenCache.expiresAt = Date.now() + (data.expires_in * 1000);

return tokenCache.accessToken;
}