Refresh Token — е специален тип дълготраен токен, предназначен за получаване на нов access token без повторно въвеждане на потребителските данни. В архитектурата на OAuth 2.0 и OpenID Connect access token има кратък живот (15–60 минути), а refresh token — значително по-дълъг (от няколко часа до месеци). Според IETF RFC 6749, 2012, refresh token позволява безпрепятствено удостовяване: потребителят вляза веднъж, а приложението автоматично обновява достъпа, без да прекъсва работата.
Основни положения
Refresh Token — са удостоверения, които клиентското приложение използва за да получи нов access token след изтичането на текущия. За разлика от access token, refresh token не се изпраща с всяка API заявка — съхранява се в безопасно хранилище на клиента и се използва само при достъп до token endpoint на сервъра за удостовяване.
Основната идея е разделянето на два токена с различен живот. Access token с кратък TTL намалява прозореца за атака при прехващането му: ако access token бъде откраден, нападателят може да го използва само няколко минути. Refresh token е защитен от това, че никога не се предава с обикновени заявки — само през защитен канал към token endpoint. Това прави кражбата му значително по-трудна.
Според OAuth Security Workshop, 2025, внедряването на refresh token с rotation намалява риска от компрометиране на сесията с 85% в сравнение с съхраняването на един дълготраен access token.
Процесът на обновяване се запуска, когато клиентът получи HTTP 401 Unauthorized отговор или открие, че access token е изтекъл (проверка на exp в JWT). Клиентът изпраща POST заявка до token endpoint на сервъра с grant_type=refresh_token и самия refresh token в тялото на заявката. Сервърът проверява валидността на refresh token, срока му на годност и принадлежността към client_id. Ако всичко е наред — сервърът връща нов access token и, по искане, нов refresh token.
Схемата на заявката за обновяване изглежда така: клиентът изпраща POST към /oauth/token с параметри grant_type=refresh_token, refresh_token={token} и client_id={id}. Сервърът връща JSON с новия access token и изтичане:
{
"access_token": "eyJhbGciOi...nowy-token",
"token_type": "Bearer",
"expires_in": 1800,
"refresh_token": "nowy-refresh-token"
}
Refresh token rotation (връщане на нов refresh token) се препоръчва от OAuth 2.0 Security Best Current Practice (RFC 9700). Старият refresh token се анулира при това. Ако нападателят откраде стария refresh token и успее да го използва преди легитимния клиент, сервърът ще открие повторна употреба — reuse detection — и ще блокира цялата сесия.
Access token и refresh token изпълняват различни функции и имат основно различни характеристики на сигурност. Access token е временен пропуск за API, refresh token е дългосрочно разрешение за получаване на нови пропуски.
| Параметър | Access Token | Refresh Token |
|---|---|---|
| Живот | 15–60 минути | Дни, седмици или месеци |
| Честота на предаване | Всяка API заявка | Само при обновяване |
| Хранилище на клиента | Памет / краткосрочно | Безопасно (Keychain / EncryptedSharedPrefs) |
| Scope | Определен набор права | Пълен обхват на правата на потребителя |
| Оттегляне | Чрез кратък TTL | Сървърна blacklist / изтриване |
| Формат | JWT или opaque | Обикновено opaque (случаен низ) |
Кратък TTL на access token — е съзнателен компромис на сигурността. Ако access token бъде откраден (чрез прехващане на трафик, изтичане на логове, злонамерен софтуер на устройството), времето, през което нападателят може да го използва, е ограничено до 15–60 минути. Refresh token е защитен от това, че никога не се предава с всяка заявка — прехващането му изисква целенасочена атака срещу token endpoint. Според Auth0 Security Team, 2025, 90% от компрометираните access token са прехванати чрез незащитени мрежови връзки — това, от което refresh token е защитен от своята архитектура.
Сигурност на refresh token — критичен елемент на цялата схема за удостовяване. Тъй като refresh token осигурява пълен достъп до профила за дълъг период, защитата му трябва да бъде максимална. OWASP и OAuth Security Best Practices публикуват конкретни изисквания.
Правилното съхранение зависи от платформата. На iOS — Keychain с достъп kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly. Това гарантира, че токенът не е наличен, когато паролата на устройството е премахната. На Android — EncryptedSharedPreferences от AndroidX Security Library с основен ключ в Android Keystore. Токенът е шифрован на ниво файлова система и е недостъпен дори и с root достъп. Забранено: да се съхранява refresh token в SharedPreferences, NSUserDefaults, plain-text файлове или в Base64 без шифроване.
Според Google Security Blog, 2025, EncryptedSharedPreferences с AES256-GCM намаляват риска от изтичане на токени с 99.7% в сравнение с обикновените SharedPreferences при физически достъп до устройството. За усилване на сигурността се препоръчва също разделяне на хранилищата: access token може да се съхранява в оперативната памет (краткосрочен достъп), refresh token — само в защитеното системно хранилище (Keychain / Keystore). Ако приложението получи foreground сигнал от системата, refresh token се проверява за валидност и при необходимост се обновява, преди потребителят да започне взаимодействие.
Refresh token rotation — е механизъм, при който всяка заявка за обновяване на access token връща нов refresh token, а старият се анулира. Ако нападателят откраде refresh token и го използва, легитимният клиент ще получи грешка при следващия опит за обновяване — сервърът ще открие, че refresh token вече е използван (reuse detection). Rotation е задължителна препоръка на OAuth 2.0 Security Best Current Practice (RFC 9700) за всички системи, работещи с дълготрайни токени в мобилна среда.
Алгоритъмът на detection работи по следния начин: сервърът съхранява в базата данни ознак „used” за всеки издаден refresh token. При заявка за обновяване сервърът проверява — ако refresh token вече е маркиран като използван, това означава опит за повторна употреба. Сервърът незабавно анулира всички refresh token на тази сесия и блокира достъпа. Легитимният потребител се пренасочва към страницата за вход. Това предотвратява атаки с кражба на refresh token: нападателят получава достъп, но сесията се блокира незабавно след откриване.
Според OAuth Security Workshop, 2025, при внедряване на rotation + reuse detection вероятността за успешна атака чрез откраден refresh token намалява от 23% на 0.3%. За имплементация на reuse detection сервърът съхранява hash на последния издаден refresh token заедно с client_id. При заявка за обновяване сервърът сравнява представения refresh token с съхранения — ако не съвпадат, това означава повторна употреба и цялата верига от токени се анулира.
При получаване на грешка invalid_grant клиентът трябва да изпълни пълен логаут: да изчисти всички запазени токени (access и refresh), да приключи текущата сесия на устройството и да пренасочи потребителя към екрана за вход. Повторното удостовяване създава нова верига от токени, която не е свързана с предишната. Игнорирането на тази грешка и повторните опити за обновяване ще доведат до блокиране чрез reuse detection.
Пример за имплементация на клиентската част за обновяване на токена в Kotlin за Android. Приложението прехваща HTTP 401 отговора, извиква заявка за обновяване и повтаря оригиналната заявка с новия access token. Използва се OkHttp Interceptor — ключов компонент за автоматично управление на токените без дублиране на логика в всяка заявка.
class AuthInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val accessToken = getAccessToken()
val authRequest = request.newBuilder()
.addHeader("Authorization", "Bearer $accessToken")
.build()
val response = chain.proceed(authRequest)
if (response.code != 401) return response
// Access token изтече — обновяваме чрез refresh token
val newToken = refreshAccessToken() ?: return response
return chain.proceed(request.newBuilder()
.addHeader("Authorization", "Bearer $newToken")
.build())
}
private fun refreshAccessToken(): String? {
val refreshToken = getRefreshToken() ?: return null
val client = OkHttpClient()
val body = FormBody.Builder()
.add("grant_type", "refresh_token")
.add("refresh_token", refreshToken)
.build()
val request = Request.Builder()
.url("https://auth.example.com/oauth/token")
.post(body)
.build()
val response = client.newCall(request).execute()
val json = JSONObject(response.body?.string() ?: return null)
val newAccessToken = json.getString("access_token")
// Запазване на новия refresh token при rotation
saveTokens(newAccessToken, json.optString("refresh_token"))
return newAccessToken
}
}
Често задавани въпроси
Access token — краткотраен токен за достъп до API, предава се с всяка заявка. Refresh token — дълготраен токен за получаване на нов access token, предава се само на token endpoint. Refresh token не трябва да бъде достъпен за обикновените API крайни точки на приложението.
При всяко изтичане — обикновено на всеки 15–60 минути. Клиентът трябва да проследява времето на изтичане (проверка на exp в JWT или таймер) и да започне заявката за обновяване предварително, преди да получи 401. Това предотвратява загубата на данни при заявки, изпратени в момента на изтичане на токена.
Да, refresh token може и трябва да бъде оттеглен. Сервърът съхранява списък на активните refresh token (или тяхните hashове) в базата данни. При изход, промяна на паролата или подозрителна активност сервърът премахва записа от базата данни, и следващата заявка за обновяване с този токен ще върне грешка invalid_grant.
При внедрена rotation с reuse detection: първата заявка успешно обновява токените, втората получава грешка invalid_grant. Сервърът също записва повторната употреба — сесията се блокира, и двамата клиенти губят достъп. Потребителят трябва да влезе отново. Това е жертване на удобството заради сигурността.
Refresh token трябва да се съхранява в Keychain с атрибут kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly. Това гарантира шифроване на токена, недостъпност при премахване на паролата и изключва синхронизация чрез iCloud. Използването на UserDefaults или CoreData за съхранение на токена е категорично забранено.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също