JWT (JSON Web Token) — је компактан формат преноса података између страна у облику JSON објекта заштићеног дигиталним потписом. Токен може бити потписан помоћу HMAC (симетрични кључ) или RSA/ECDSA (асиметрични пар), што гарантује интегритет и аутентичност података. Према IETF RFC 7519, 2015, JWT се користи у милионима апликација за аутентификацију, безбедну размену claims и као формат ID Token у OpenID Connect.
Главно
JSON Web Token (JWT) — је отворени стандард (RFC 7519) који дефинише компактан и самодовољан начин преноса информација између страна у облику JSON објекта. Информације у JWT се називају claims — тврдње о субјекту (кориснику) и додатним атрибутима. Сваки claim је пар кључ-вредност: идентификатор корисника, улога, време истека, издавач.
JWT се назива самодовољним јер се све информације потребне за проверу налазе унутар самог токена. Сервер не мора да приступа бази података или спољашњем складишту да би се уверио у валидност токена — довољно је проверити потпис. Ово својство чини JWT идеалним за дистрибуиране системе и микросервисну архитектуру, где више сервиса мора да аутентификује захтеве без заједничког складишта сесија.
Према подацима Auth0, 2025, више од 65% мобилних и веб апликација користи JWT као основни формат токена за API аутентификацију, престижући opaque токене и идентификаторе сесија.
JWT се састоји од три дела раздвојена тачкама: header.payload.signature. Сваки део је Base64url-кодирани JSON. Хајде да детаљно размотримо сваки део.
Header садржи два обавезна поља: alg (algorithm — алгоритам потписа) и typ (type — тип токена, увек „JWT”). Алгоритам може бити симетричан (HS256 — HMAC са SHA-256) или асиметричан (RS256 — RSA са SHA-256, ES256 — ECDSA са P-256). Асиметрични алгоритми су пожељнији јер омогућавају клијенту да провери потпис без поседовања тајног кључа.
Пример декодираног header-а:
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-id-1"
}
Payload садржи claims — тврдње о субјекту. Claims се деле на три типа: регистровани (iss, sub, aud, exp, nbf, iat, jti), јавни (дефинисани од стране програмера у IANA Registry) и приватни (договорени између страна). sub (subject) — јединствени идентификатор корисника. exp (expiration) — временска ознака истека токена. iss (issuer) — издавач токена.
{
"sub": "user-abc-123",
"iss": "https://auth.example.com",
"aud": "my-mobile-app",
"exp": 1812345678,
"iat": 1812342078,
"role": "premium_user"
}
Signature се креира применом алгоритма потписа на конкатенацију header-а и payload-а користећи тајни или приватни кључ. Формула: HMACSHA256(base64UrlEncode(header) + „.” + base64UrlEncode(payload), secret) за HMAC, или RSASHA256(...) за асиметрични алгоритам. Прималац израчунава потпис на исти начин и упоређује га са добијеним — ако се поклапају, подаци нису измењени.
Процес рада са JWT састоји се из две фазе: креирање (издавање) токена од стране сервера за аутентификацију и провера токена од стране клијента или сервера ресурса. Сервер за аутентификацију прима акредитиве корисника, креира payload са claims и потписује га. Добијени JWT се шаље клијенту у одговору на захтев за пријаву или у телу одговора OAuth 2.0 / OpenID Connect.
У мобилним апликацијама JWT се користи на следећи начин: након успешне пријаве, корисник добија access token у JWT формату. Апликација га чува у заштићеном складишту (Keychain на iOS, EncryptedSharedPreferences на Android-у). При сваком захтеву ка API-ју, апликација додаје заглавље Authorization: Bearer <token>. Сервер API проверава потпис JWT, издваја claims и на основу њих доноси одлуку о приступу — без приступа бази података.
Према подацима Google Codelabs, 2025, употреба JWT у Firebase Authentication смањује број захтева ка серверу за аутентификацију за 40–60% у поређењу са сесијским токенима, јер се подаци проверавају локално на сваком микросервису. Ово је посебно важно за архитектуре са високим оптерећењем, где свака милисекунда кашњења утиче на корисничко искуство. При 50 000 захтева у минути, прелазак на JWT може уштедети до 10 серверских инстанци које обрађују introspection захтеве.
JWT и Session Token решавају исти задатак — аутентификацију захтева — али се суштински разликују по архитектури. Session Token је случајни идентификаторски низ који упућује на податке сесије ускладиштене на серверу (stateful). JWT — самодовољан токен који садржи све податке у себи (stateless).
| Параметар | JWT | Session Token |
|---|---|---|
| Чување података | Унутар токена (самодовољан) | На серверу (складиште сесије) |
| Скалирање | Не захтева заједничко складиште | Захтева Redis/БД за више сервера |
| Опозив токена | Компликован (потребна црна листа) | Једноставан (брисање сесије из БД) |
| Величина | Велика (500–2000 бајтова) | Мала (16–64 бајта) |
| Провера потписа | Криптографска | Нема (поређење низова) |
JWT побеђује у дистрибуираним системима: микросервиси могу локално да провере токен без заједничког складишта. На пример, у архитектури са пет микросервиса, сваки сервис проверава JWT за 1–2 ms без мрежног позива, док session token захтева обраћање централизованом Redis-у при сваком захтеву, додајући 10–30 ms кашњења. Међутим, JWT је тешко опозвати — ако је токен већ издат, важи до истека. Session Token се лако опозива брисањем записа из БД или Redis-а.
За мобилне апликације, комбиновани приступ — JWT са кратким веком трајања (15–30 минута) и Refresh Token — даје равнотежу између перформанси и безбедности. JWT се користи за приступ API-ју, а refresh token (обично opaque) за добијање нових JWT-ова. При компромитацији JWT-а, нападач има приступ 15–30 минута; при компромитацији refresh token-а, сесија се блокира путем ротације и детекције поновне употребе.
Безбедност JWT зависи од правилне имплементације. Најчешћа рањивост је напад „alg none”: нападач мења header токена у „alg”: „none”, а сервер, без провере алгоритма, прихвата лажни токен. Заштита: увек проверавати да алгоритам у header-у одговара очекиваном (RS256, ES256) и одбијати токене са alg: none.
Рањивости JWT такође укључују: слаб тајни кључ за HMAC (пробијање за неколико минута), цурење приватног кључа (потписивање произвољних података у име сервера), чување осетљивих података у payload-у (JWT не шифрује, само потписује), напад путем JWK header injection-а (убацивање сопственог јавног кључа). Употреба проверених библиотека — Nimbus JOSE + JWT, jjwt (io.jsonwebtoken), PyJWT — смањује ризик од експлоатације ових рањивости.
Додатна мера заштите — JWK Thumbprint (RFC 7638): повезивање јавног кључа са токеном путем отиска (thumbprint) у header-у. Ако сервер чува очекивани thumbprint за сваког клијента, напад JWK header injection постаје немогућ — сервер одбија сваки кључ који се не поклапа са регистрованим. OAuth Security Workshop 2025 препоручује JWK Thumbprint као обавезну заштиту за све JWT који се користе у финансијским и медицинским апликацијама.
Библиотека jjwt (auth0/java-jwt) омогућава креирање и проверу JWT-ова у Android апликацији у неколико редова. У примеру испод, сервер генерише токен са sub и role, а клијент проверава потпис. За безбедно чување тајног кључа на серверу користите променљиве окружења или HSM (Hardware Security Module) — чување кључа у коду или конфигурационом фајлу је груба безбедносна грешка.
val secret = "my-256-bit-secret-key-here"
val token = JWT.create()
.withSubject("user-abc-123")
.withIssuer("auth.example.com")
.withClaim("role", "premium_user")
.withExpiresAt(Date(System.currentTimeMillis() + 3600000))
.sign(Algorithm.HMAC256(secret))
// Слање токена клијенту
println("JWT: $token")
fun verifyToken(token: String): Boolean {
return try {
val decoded = JWT.require(Algorithm.HMAC256(secret))
.withIssuer("auth.example.com")
.build()
.verify(token)
// Потпис је исправан, claims издвојени
println("Subject: ${decoded.subject}")
true
} catch (e: Exception) {
println("Token invalid: ${e.message}")
false
}
}
Често постављана питања
Не. JWT се потписује, а не шифрује — свако може да декодира Base64 payload и прочита податке. Осетљиве информације (лозинке, бројеви картица, лични подаци) треба преносити само у шифрованом облику путем JWE (JSON Web Encryption).
Препоручује се ES256 (ECDSA са P-256) — пружа еквивалентан RSA 2048-bit ниво безбедности уз значајно мању величину потписа. За компатибилност са застарелим системима одговара RS256. HS256 (HMAC) захтева безбедну размену тајног кључа, што је теже у дистрибуираној архитектури.
JWT се не може директно опозвати — важи до exp. Решења: користити кратак век трајања (15–30 минута), водити црну листу опозваних jti (JWT ID) на серверу, или повезати токене са верзијом тајног кључа. Refresh token се притом опозива стандардним начином — брисањем из складишта.
Bearer token — је концепт: сваки токен који носилац (bearer) може да користи за приступ. JWT — је специфичан формат токена. Bearer token може бити JWT или opaque низ. JWT додаје концепту Bearer самодовољност и криптографску верификацију.
Типичан JWT са RS256 потписом заузима 500–2000 бајтова. Ако payload садржи много прилагођених claims или се користи асиметрични потпис са великим кључем, величина може достићи 4–5 KB. Ово је значајно више од session token-а (16–64 бајта), што утиче на величину HTTP заглавља.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође