JWT (JSON Web Token) — είναι μια συμπαγής μορφή μεταφοράς δεδομένων μεταξύ μερών με τη μορφή ενός αντικειμένου JSON που προστατεύεται από ψηφιακή υπογραφή. Το token μπορεί να υπογραφεί με HMAC (συμμετρικό κλειδί) ή RSA/ECDSA (ασύμμετρο ζεύγος), που εγγυάται την ακεραιότητα και την αυθεντικότητα των δεδομένων. Σύμφωνα με το IETF RFC 7519, 2015, το JWT χρησιμοποιείται σε εκατομμύρια εφαρμογές για αυθεντικοποίηση, ασφαλή ανταλλαγή claims και ως μορφή ID Token στο OpenID Connect.
Κύρια σημεία
JSON Web Token (JWT) — είναι ένα ανοιχτό πρότυπο (RFC 7519) που ορίζει έναν συμπαγή και αυτοδύναμο τρόπο μεταφοράς πληροφοριών μεταξύ μερών με τη μορφή ενός αντικειμένου JSON. Οι πληροφορίες στο JWT ονομάζονται claims — ισχυρισμοί για το υποκείμενο (χρήστη) και πρόσθετα χαρακτηριστικά. Κάθε claim είναι ένα ζεύγος κλειδιού-τιμής: αναγνωριστικό χρήστη, ρόλος, χρόνος λήξης, εκδότης.
Το JWT ονομάζεται αυτοδύναμο επειδή όλες οι πληροφορίες που απαιτούνται για επαλήθευση βρίσκονται μέσα στο ίδιο το token. Ο διακομιστής δεν χρειάζεται να έχει πρόσβαση σε βάση δεδομένων ή εξωτερική αποθήκευση για να βεβαιωθεί για την εγκυρότητα του token — αρκεί να ελέγξει την υπογραφή. Αυτή η ιδιότητα καθιστά το JWT ιδανικό για κατανεμημένα συστήματα και αρχιτεκτονική μικροϋπηρεσιών, όπου πολλές υπηρεσίες πρέπει να αυθεντικοποιούν αιτήματα χωρίς κοινόχρηστη αποθήκευση συνεδριών.
Σύμφωνα με δεδομένα της Auth0, 2025, πάνω από το 65% των εφαρμογών κινητών και web χρησιμοποιούν JWT ως κύρια μορφή token για αυθεντικοποίηση API, ξεπερνώντας τα opaque tokens και τα αναγνωριστικά συνεδρίας.
Το JWT αποτελείται από τρία μέρη χωρισμένα με τελείες: header.payload.signature. Κάθε μέρος είναι ένα JSON κωδικοποιημένο σε Base64url. Ας εξετάσουμε κάθε μέρος λεπτομερώς.
Το Header περιέχει δύο υποχρεωτικά πεδία: alg (algorithm — αλγόριθμος υπογραφής) και typ (type — τύπος token, πάντα “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) — χρονική σήμανση λήξης token. iss (issuer) — εκδότης token.
{
"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 αποτελείται από δύο φάσεις: δημιουργία (έκδοση) του token από τον διακομιστή αυθεντικοποίησης και επαλήθευση του token από τον πελάτη ή τον διακομιστή πόρων. Ο διακομιστής αυθεντικοποίησης λαμβάνει τα διαπιστευτήρια του χρήστη, δημιουργεί 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% σε σύγκριση με τα tokens συνεδρίας, επειδή τα δεδομένα επαληθεύονται τοπικά σε κάθε μικροϋπηρεσία. Αυτό είναι ιδιαίτερα σημαντικό σε αρχιτεκτονικές υψηλού φορτίου, όπου κάθε χιλιοστό του δευτερολέπτου καθυστέρησης επηρεάζει την εμπειρία χρήστη. Σε 50.000 αιτήματα ανά λεπτό, η μετάβαση σε JWT μπορεί να εξοικονομήσει έως 10 στιγμιότυπα διακομιστή που επεξεργάζονται αιτήματα introspection.
Το JWT και το Session Token λύνουν την ίδια εργασία — αυθεντικοποίηση αιτημάτων — αλλά διαφέρουν θεμελιωδώς στην αρχιτεκτονική. Το Session Token είναι μια τυχαία συμβολοσειρά αναγνωριστικού που αναφέρεται σε δεδομένα συνεδρίας αποθηκευμένα στον διακομιστή (stateful). Το JWT — αυτοδύναμο token που περιέχει όλα τα δεδομένα μέσα του (stateless).
| Παράμετρος | JWT | Session Token |
|---|---|---|
| Αποθήκευση δεδομένων | Μέσα στο token (αυτοδύναμο) | Στον διακομιστή (αποθήκευση συνεδρίας) |
| Κλιμάκωση | Δεν απαιτεί κοινόχρηστη αποθήκευση | Απαιτεί Redis/DB για πολλούς διακομιστές |
| Ανάκληση token | Πολύπλοκη (χρειάζεται μαύρη λίστα) | Απλή (διαγραφή συνεδρίας από DB) |
| Μέγεθος | Μεγάλο (500–2000 byte) | Μικρό (16–64 byte) |
| Επαλήθευση υπογραφής | Κρυπτογραφική | Όχι (σύγκριση συμβολοσειρών) |
Το JWT υπερέχει σε κατανεμημένα συστήματα: οι μικροϋπηρεσίες μπορούν να επαληθεύουν το token τοπικά χωρίς κοινόχρηστη αποθήκευση. Για παράδειγμα, σε μια αρχιτεκτονική με πέντε μικροϋπηρεσίες, κάθε υπηρεσία επαληθεύει το JWT σε 1–2 ms χωρίς κλήση δικτύου, ενώ το session token απαιτεί πρόσβαση σε κεντρικοποιημένο Redis σε κάθε αίτημα, προσθέτοντας 10–30 ms καθυστέρηση. Ωστόσο, το JWT είναι δύσκολο να ανακληθεί — αν το token έχει ήδη εκδοθεί, ισχύει μέχρι τη λήξη. Το Session Token ανακλείται εύκολα με διαγραφή της εγγραφής από DB ή Redis.
Για εφαρμογές κινητών, η συνδυασμένη προσέγγιση — JWT με σύντομη διάρκεια ζωής (15–30 λεπτά) και Refresh Token — παρέχει ισορροπία μεταξύ απόδοσης και ασφάλειας. Το JWT χρησιμοποιείται για πρόσβαση στο API, και το refresh token (συνήθως opaque) για λήψη νέων JWT. Σε περίπτωση παραβίασης του JWT, ο επιτιθέμενος έχει πρόσβαση για 15–30 λεπτά; σε περίπτωση παραβίασης του refresh token, η συνεδρία μπλοκάρεται μέσω περιστροφής και ανίχνευσης επαναχρησιμοποίησης.
Η ασφάλεια του JWT εξαρτάται από τη σωστή υλοποίηση. Η πιο κοινή ευπάθεια είναι η επίθεση “alg none”: ο επιτιθέμενος τροποποιεί το header του token σε “alg”: “none” και ο διακομιστής, χωρίς να ελέγξει τον αλγόριθμο, αποδέχεται το πλαστό token. Προστασία: πάντα να ελέγχετε ότι ο αλγόριθμος στο header αντιστοιχεί στον αναμενόμενο (RS256, ES256) και να απορρίπτετε tokens με alg: none.
Οι ευπάθειες του JWT περιλαμβάνουν επίσης: αδύναμο μυστικό κλειδί για HMAC (σπάσιμο εντός λεπτών), διαρροή ιδιωτικού κλειδιού (υπογραφή οποιωνδήποτε δεδομένων στο όνομα του διακομιστή), αποθήκευση ευαίσθητων δεδομένων στο payload (το JWT δεν κρυπτογραφεί, μόνο υπογράφει), επίθεση μέσω JWK header injection (εισαγωγή δικού σας δημόσιου κλειδιού). Η χρήση επαληθευμένων βιβλιοθηκών — Nimbus JOSE + JWT, jjwt (io.jsonwebtoken), PyJWT — μειώνει τον κίνδυνο εκμετάλλευσης αυτών των ευπαθειών.
Ένα πρόσθετο μέτρο προστασίας — JWK Thumbprint (RFC 7638): σύνδεση του δημόσιου κλειδιού με το token μέσω αποτυπώματος (thumbprint) στο header. Εάν ο διακομιστής αποθηκεύει το αναμενόμενο thumbprint για κάθε πελάτη, η επίθεση JWK header injection καθίσταται αδύνατη — ο διακομιστής απορρίπτει κάθε κλειδί που δεν ταιριάζει με το καταχωρημένο. Το OAuth Security Workshop 2025 συνιστά το JWK Thumbprint ως υποχρεωτική προστασία για όλα τα JWT που χρησιμοποιούνται σε χρηματοοικονομικές και ιατρικές εφαρμογές.
Η βιβλιοθήκη jjwt (auth0/java-jwt) επιτρέπει τη δημιουργία και επαλήθευση JWT σε εφαρμογή Android σε λίγες γραμμές. Στο παρακάτω παράδειγμα, ο διακομιστής δημιουργεί ένα token με 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))
// Αποστολή token στον πελάτη
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) στον διακομιστή, ή σύνδεση tokens με την έκδοση του μυστικού κλειδιού. Το refresh token ανακαλείται με τυπικό τρόπο — με διαγραφή από την αποθήκευση.
Bearer token — είναι μια έννοια: οποιοδήποτε token που μπορεί να χρησιμοποιήσει ο κάτοχος (bearer) για πρόσβαση. JWT — είναι μια συγκεκριμένη μορφή token. Το Bearer token μπορεί να είναι JWT ή opaque συμβολοσειρά. Το JWT προσθέτει στην έννοια Bearer αυτοδυναμία και κρυπτογραφική επαλήθευση.
Ένα τυπικό JWT με υπογραφή RS256 καταλαμβάνει 500–2000 byte. Εάν το payload περιέχει πολλά προσαρμοσμένα claims ή χρησιμοποιείται ασύμμετρη υπογραφή με μεγάλο κλειδί, το μέγεθος μπορεί να φτάσει τα 4–5 KB. Αυτό είναι σημαντικά μεγαλύτερο από το session token (16–64 byte), που επηρεάζει το μέγεθος των κεφαλίδων HTTP.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης