Twoje API jest tak bezpieczne, jak jego najsłabsze ogniwo
Każda aplikacja webowa komunikująca się z backendem korzysta z jakiegoś API. Niezależnie od tego, czy to publiczny REST API, wewnętrzny endpoint czy integracja z usługą zewnętrzną — bezpieczeństwo tej komunikacji jest kluczowe. Źle zabezpieczone API to otwarte drzwi dla atakujących.
W tym artykule omawiamy najważniejsze metody uwierzytelniania i autoryzacji API oraz najlepsze praktyki ich stosowania.
Uwierzytelnianie vs autoryzacja — ważna różnica
Te dwa pojęcia są często mylone, a oznaczają zupełnie różne rzeczy:
- Uwierzytelnianie (authentication) — odpowiada na pytanie: "Kim jesteś?" Potwierdza tożsamość użytkownika lub systemu
- Autoryzacja (authorization) — odpowiada na pytanie: "Co możesz zrobić?" Określa, jakie zasoby i operacje są dostępne dla uwierzytelnionego podmiotu
Można być uwierzytelnionym (system wie, kim jesteś), ale nieautoryzowanym do konkretnej operacji (nie masz uprawnień do usunięcia tego zasobu). Poprawne rozdzielenie tych dwóch mechanizmów to fundament bezpiecznego API.
Klucze API — proste, ale ograniczone
Klucz API to losowy ciąg znaków przesyłany w nagłówku żądania HTTP:
Authorization: ApiKey sk_live_abc123def456
Zalety: prostota implementacji, łatwość dystrybucji, brak stanu po stronie serwera (wystarczy sprawdzić klucz w bazie).
Wady: klucz nie wygasa automatycznie, nie niesie informacji o uprawnieniach, łatwo go przypadkowo ujawnić (np. w repozytorium Git).
Kiedy stosować: komunikacja serwer-serwer, integracje z usługami zewnętrznymi, proste wewnętrzne API. Nigdy jako jedyna metoda uwierzytelniania użytkowników końcowych.
Najlepsze praktyki dla kluczy API:
- Generuj klucze o wysokiej entropii (minimum 32 bajty losowe)
- Przechowuj w bazie jako hash, nie jako plaintext
- Implementuj rotację kluczy — możliwość wygenerowania nowego klucza bez przerwy w działaniu
- Dodaj prefiksy identyfikujące typ klucza (
sk_live_,sk_test_) - Monitoruj użycie i ustaw limity żądań (rate limiting)
JWT — tokeny z wbudowanymi danymi
JSON Web Token (JWT) to standard umożliwiający przekazywanie informacji między stronami w postaci podpisanego tokenu. JWT składa się z trzech części oddzielonych kropkami: nagłówka (header), ładunku (payload) i podpisu (signature).
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMjN9.sIGnature
Payload może zawierać dowolne dane — identyfikator użytkownika, rolę, czas wygaśnięcia:
{
"user_id": 123,
"role": "admin",
"exp": 1704067200
}
Zalety: bezstanowość (serwer nie musi przechowywać sesji), samowystarczalność (token zawiera potrzebne dane), skalowalność.
Wady: nie można unieważnić pojedynczego tokenu bez dodatkowej infrastruktury (np. blacklisty), token może być duży, dane w payload są kodowane (Base64), ale nie zaszyfrowane — każdy może je odczytać.
Najważniejsze zasady bezpieczeństwa JWT:
- Krótki czas życia — access token powinien wygasać po 15-30 minutach. Do odświeżania służy osobny refresh token z dłuższym czasem życia
- Używaj algorytmu HS256 lub RS256 — nigdy
none. Weryfikuj algorytm po stronie serwera - Nie przechowuj wrażliwych danych w payload — hasła, numery kart, tokeny API nie mają tam czego szukać
- Przechowuj w httpOnly cookies, nie w
localStorage— to chroni przed atakami XSS - Waliduj WSZYSTKIE pola —
exp,iss,aud— nie tylko podpis
OAuth 2.0 — delegowane uwierzytelnianie
OAuth 2.0 to framework autoryzacji pozwalający aplikacji uzyskać ograniczony dostęp do zasobów użytkownika w innym serwisie, bez poznawania jego hasła. To mechanizm stojący za przyciskami "Zaloguj się przez Google/GitHub/Facebook".
OAuth 2.0 definiuje kilka przepływów (flows), z których najważniejsze to:
- Authorization Code Flow — najpopularniejszy i najbezpieczniejszy. Użytkownik jest przekierowywany do serwera autoryzacji, loguje się, a aplikacja otrzymuje kod autoryzacyjny, który wymienia na token
- Authorization Code Flow z PKCE — rozszerzenie powyższego dla aplikacji publicznych (SPA, mobile), eliminujące potrzebę client secret
- Client Credentials Flow — dla komunikacji serwer-serwer, bez udziału użytkownika
Ważne: OAuth 2.0 to framework autoryzacji, nie uwierzytelniania. Do uwierzytelniania służy nadbudówka OpenID Connect (OIDC), która dodaje token ID zawierający informacje o tożsamości użytkownika.
Najlepsze praktyki bezpieczeństwa API
Niezależnie od wybranej metody uwierzytelniania, stosuj te zasady:
- HTTPS zawsze — nigdy nie przesyłaj tokenów przez nieszyfrowane połączenie. Konfiguruj HSTS, aby wymusić szyfrowanie
- Rate limiting — ogranicz liczbę żądań na jednostkę czasu. Chroni przed atakami brute-force i nadmiernym zużyciem zasobów
- Walidacja danych wejściowych — każdy parametr żądania musi być walidowany. Nigdy nie ufaj danym od klienta
- Logowanie i monitoring — rejestruj nieudane próby uwierzytelniania, nietypowe wzorce dostępu, żądania z nieznanych lokalizacji
- CORS — skonfiguruj nagłówki Cross-Origin Resource Sharing, aby ograniczyć, które domeny mogą wykonywać żądania do API
- Wersjonowanie API — pozwala na bezpieczne wprowadzanie zmian bez łamania istniejących integracji
- Minimalne uprawnienia — tokeny i klucze powinny mieć tylko te uprawnienia, które są faktycznie potrzebne
Częste błędy, których warto unikać
Z naszego doświadczenia, najczęstsze problemy z bezpieczeństwem API to:
- Przechowywanie tokenów w
localStorage(podatność na XSS) - Brak walidacji tokenu po stronie serwera (sprawdzanie tylko obecności, nie poprawności)
- Zbyt długi czas życia access tokenów (godziny lub dni zamiast minut)
- Brak rate limitingu na endpointach logowania
- Ujawnianie szczegółowych komunikatów błędów (np. "Nieprawidłowe hasło" zamiast "Nieprawidłowe dane logowania")
- Przesyłanie kluczy API w parametrach URL (zapisywane w logach serwera)
Podsumowanie
Bezpieczeństwo API to nie jednorazowa konfiguracja, ale ciągły proces. Klucze API sprawdzają się w prostych integracjach serwer-serwer, JWT doskonale nadaje się do bezstanowego uwierzytelniania użytkowników, a OAuth 2.0 jest standardem dla delegowanego dostępu do zasobów.
Najważniejsza zasada? Nie wymyślaj własnych mechanizmów bezpieczeństwa. Korzystaj z przetestowanych standardów i bibliotek, regularnie aktualizuj zależności i monitoruj logi pod kątem podejrzanej aktywności.
Potrzebujesz audytu bezpieczeństwa swojego API lub pomocy w implementacji uwierzytelniania? Skontaktuj się z nami.