Access Token — to dane uwierzytelniające, które aplikacja kliencka przedstawia serwerowi w celu uzyskania dostępu do chronionych zasobów API. Po uwierzytelnieniu użytkownika serwer autoryzacji wydaje access token, który klient przekazuje w nagłówku HTTP Authorization przy każdym żądaniu. Według danych OAuth.net, 2025, access token może być opaque string (ciąg znaków bez znaczenia) lub JWT (samowystarczalny token z danymi wewnątrz) — wybór formatu zależy od architektury i wymagań dotyczących wydajności systemu.
Najważniejsze
Access Token — to ciąg znaków, którego klient (aplikacja mobilna, SPA, serwer) używa do uwierzytelniania żądań HTTP do chronionych endpointów API. Token jest wydawany przez serwer autoryzacji po potwierdzeniu przez użytkownika swojej tożsamości i udzieleniu aplikacji odpowiednich uprawnień (scope).
Access token jest centralnym elementem protokołu OAuth 2.0 i wszystkich zbudowanych na nim systemów — OpenID Connect, Firebase Authentication, Auth0, Keycloak. Bez access token żadne żądanie do chronionego API nie zostanie przetworzone: serwer zwraca HTTP 401 Unauthorized. Token nie identyfikuje użytkownika bezpośrednio — potwierdza, że klient ma prawo wykonać konkretną czynność w imieniu użytkownika (autoryzacja), a nie to, kim jest użytkownik (uwierzytelnianie).
Według danych Okta, 2025, ponad 80% publicznych API używa schematu Bearer z access token w nagłówku Authorization, wypierając przestarzałe metody uwierzytelniania — Basic Auth i API Key. Access token jest również podstawą delegated authorization — modelu, w którym użytkownik udziela aplikacji ograniczonego dostępu do swoich danych w innym serwisie. Na przykład, gdy aplikacja mobilna do edycji zdjęć żąda dostępu do Google Drive przez OAuth 2.0, użytkownik widzi ekran zgody z wymienionymi konkretnymi scope i po potwierdzeniu otrzymuje access token z tymi uprawnieniami.
Mechanizm działania access token opiera się na schemacie Bearer: klient dodaje nagłówek Authorization: Bearer <token> do każdego żądania HTTP. Serwer zasobów (API) otrzymuje token, sprawdza jego ważność i określa, które zasoby są dostępne. Weryfikacja może odbywać się na dwa sposoby: lokalnie (dla JWT) lub przez introspection endpoint (dla opaque token).
Bearer token oznacza, że każdy, kto przedstawi token (bearer — okaziciel), uzyskuje odpowiedni dostęp. Nakłada to wysokie wymagania dotyczące ochrony tokena podczas transmisji i przechowywania. Schemat Bearer nie wymaga od klienta kryptograficznego udowodnienia posiadania tokena — wystarczy go po prostu przekazać. Dlatego HTTPS jest obowiązkowe: bez szyfrowania ruchu osoba atakująca może przechwycić token i natychmiast go użyć.
Według danych Cloudflare, 2025, przechwycenie Bearer token przez niezabezpieczone połączenie HTTP następuje średnio w 12 sekund po wysłaniu żądania. Użycie HTTPS i krótkiego TTL access token (15–30 minut) sprowadza ryzyko praktycznie do zera. Dodatkowa ochrona na poziomie aplikacji — weryfikacja origin żądania przez OAuth 2.0 Token Binding (RFC 8471): klient udowadnia posiadanie klucza TLS powiązanego z tokenem, co czyni kradzież tokena przez przechwycenie bezużyteczną.
Access token istnieje w dwóch formatach: opaque (nieprzezroczysty) i JWT (samowystarczalny). Wybór między nimi to jedna z kluczowych decyzji architektonicznych przy projektowaniu systemu uwierzytelniania.
| Parametr | Opaque Token | JWT |
|---|---|---|
| Format | Losowy ciąg znaków (32–64 bajty) | Base64-zakodowany JSON z podpisem |
| Weryfikacja | Przez introspection endpoint (żądanie HTTP) | Lokalna (podpis kryptograficzny) |
| Zawiera dane | Nie — tylko identyfikator | Tak — claims wewnątrz tokena |
| Unieważnienie | Natychmiastowe — weryfikacja na serwerze | Przez blacklist lub krótki TTL |
| Wydajność | Każde żądanie → introspection (RTT) | Weryfikacja lokalna (bez RTT) |
| Rozmiar | ~100 bajtów | ~500–2000 bajtów |
Opaque token jest preferowany dla systemów, gdzie wymagane jest natychmiastowe unieważnienie dostępu i scentralizowana weryfikacja uprawnień. JWT — dla architektury mikroserwisowej, gdzie ważna jest wydajność i minimalizacja wywołań sieciowych. Wielu dostawców (Auth0, Keycloak) obsługuje oba formaty i pozwala skonfigurować typ tokena dla każdego klienta. Wybór między opaque a JWT to kompromis między kontrolą a wydajnością: opaque daje pełną kontrolę serwerowi, JWT — minimalne opóźnienie.
Cykl życia access token składa się z czterech faz: wydanie (issuance), transmisja, użycie i wygaśnięcie. Każda faza ma swoje wymagania bezpieczeństwa i ograniczenia protokołowe.
Access token ma ograniczony czas życia — zazwyczaj 15–60 minut. Wartość expires_in jest podawana w odpowiedzi serwera autoryzacji przy wydaniu tokena. Po upływie tego czasu token staje się nieważny, a klient musi uzyskać nowy poprzez mechanizm refresh token. Klient może sprawdzać wygaśnięcie na dwa sposoby: przez pole exp w JWT (lokalnie) lub przez odpowiedź HTTP 401 (dla opaque token).
Według danych Auth0 Best Practices, 2025, optymalny TTL access token dla aplikacji mobilnych to 15–30 minut. Zbyt krótki TTL (poniżej 5 minut) tworzy nadmierne obciążenie token endpoint przy każdym odnowieniu — przy 10 000 użytkowników i TTL 5 minut serwer otrzymuje do 2 000 żądań odnowienia na minutę w godzinach szczytu. Zbyt długi TTL (powyżej 2 godzin) zwiększa okno ataku przy wycieku tokena — osoba atakująca może używać skompromitowanego tokena przez kilka godzin, zanim dostęp zostanie automatycznie zablokowany.
Bezpieczeństwo access token musi być zapewnione na wszystkich etapach: podczas przechowywania na urządzeniu, podczas transmisji przez sieć i podczas przetwarzania na serwerze. Podstawowa zasada — nigdy nie przechowywać access token w miejscach dostępnych dla innych aplikacji lub procesów.
Na urządzeniach mobilnych access token jest przechowywany: na iOS — w Keychain z atrybutem kSecAttrAccessibleAfterFirstUnlock (token dostępny po pierwszym odblokowaniu, nawet jeśli urządzenie jest zablokowane — do aktualizacji w tle); na Android — w EncryptedSharedPreferences. Access token nigdy nie powinien być zapisywany w NSUserDefaults, SharedPreferences, plikach w zewnętrznym magazynie lub w logach aplikacji. Podczas transmisji — tylko HTTPS z TLS 1.3 lub 1.2. Dla każdego żądania API access token powinien być przekazywany w nagłówku Authorization: Bearer, a nie w parametrach URL (query string) — URL trafia do logów serwerów i przeglądarek.
Według danych OWASP Mobile Top 10, 2025, nieprawidłowe przechowywanie tokenów na urządzeniu (M1: Improper Platform Usage) i niezabezpieczona transmisja danych (M3: Insecure Communication) znajdują się w pierwszej trójce najczęstszych podatności mobilnych prowadzących do kompromitacji kont. Dodatkowy środek — użycie certificate pinning dla wszystkich żądań z access token: klient weryfikuje certyfikat serwera nie tylko przez standardowy łańcuch CA, ale także przez wcześniej zapisany odcisk certyfikatu (SHA-256 fingerprint). Zapobiega to atakom man-in-the-middle nawet przy skompromitowanym CA.
Poniżej znajduje się przykład w Kotlin dla Android, demonstrujący wysyłanie żądania z access token w nagłówku Authorization i obsługę 401 z automatycznym odnowieniem przez refresh token. Użyto OkHttp z niestandardowym Interceptor.
data class TokenStore {
fun getAccessToken(): String? {
// Odczyt z EncryptedSharedPreferences
return encryptPrefs.getString("access_token", null)
}
fun isTokenExpired(): Boolean {
val expiresAt = encryptPrefs.getLong("expires_at", 0)
return System.currentTimeMillis() > expiresAt
}
}
class ApiClient(private val tokenStore: TokenStore) {
private val client = OkHttpClient.Builder()
.addInterceptor(AuthInterceptor(tokenStore))
.build()
fun fetchUserProfile(): UserProfile? {
val request = Request.Builder()
.url("https://api.example.com/user/profile")
.get()
.build()
val response = client.newCall(request).execute()
return if (response.isSuccessful) {
parseProfile(response.body?.string() ?: return null)
} else null
}
}
fun sendAuthenticatedRequest(token: String): Unit {
val conn = URL("https://api.example.com/data").openConnection() as HttpURLConnection
conn.setRequestProperty("Authorization", "Bearer $token")
conn.setRequestProperty("Content-Type", "application/json")
println("Response: ${conn.responseCode}")
}
W przykładzie pokazano dwa podejścia: z użyciem OkHttp Interceptor do automatycznego zarządzania tokenami i bezpośrednie wysyłanie przez HttpURLConnection. OkHttp Interceptor jest preferowany — centralizuje logikę dodawania i odświeżania tokena, eliminując powielanie kodu w każdym żądaniu. Wszystkie żądania przechodzą przez jeden interceptor, który sprawdza status odpowiedzi i w razie potrzeby odświeża token bez udziału programisty.
Często zadawane pytania
API key — statyczny identyfikator aplikacji, niepowiązany z konkretnym użytkownikiem. Access token — dynamiczny, tymczasowy, powiązany z użytkownikiem i sesją. API key nie obsługuje scope (ograniczenia uprawnień), podczas gdy access token może mieć różne poziomy dostępu dla różnych operacji.
Dwa sposoby: aktywny — sprawdzenie pola exp w JWT (klient sam oblicza, czy token wygasł); pasywny — wysłanie żądania i otrzymanie HTTP 401 Unauthorized. Zaleca się łączenie: wstępne sprawdzenie exp w celu zapobieżenia utracie danych i obsługa 401 jako fallback.
Nie. Access token nigdy nie powinien być przekazywany w query string URL. Parametry URL są zapisywane w historii przeglądarki, logach serwera, refererze i cache serwerów proxy. Jedynym bezpiecznym sposobem jest nagłówek Authorization: Bearer. Jest to wymóg OAuth 2.0 Security Best Practices (RFC 9700).
Zaleca się 15–30 minut. Przy tym używa się refresh token z rotacją do automatycznego odświeżania. Taki TTL balansuje bezpieczeństwo i UX: użytkownik nie zauważa odświeżeń, a okno ataku przy wycieku tokena jest minimalne. Dla szczególnie wrażliwych operacji (przelew pieniędzy) — 1–5 minut.
Bearer token — to rodzaj access token, przy którym każdy okaziciel (bearer) tokena uzyskuje dostęp. Nie wymaga kryptograficznego dowodu posiadania — wystarczy fakt przekazania tokena. Schemat Bearer jest prosty i efektywny, ale wymaga obowiązkowego HTTPS w celu ochrony przed przechwyceniem tokena w drodze.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również