कोई JWT तब एक्सपायर माना जाता है जब मौजूदा समय उसके exp क्लेम के बराबर या उसके बाद हो। exp एक सीधी संख्या है: 1 जनवरी 1970 (UTC) से अब तक बीते सेकंड। उदाहरण के लिए, 1793372400 का मतलब है 30 अक्टूबर 2026, 15:00:00 UTC, यानी भारत में रात 8:30 बजे। टोकन एक्सपायर हुआ या नहीं, यह जानने के लिए उसका बीच वाला हिस्सा डिकोड करें, exp पढ़ें और उसे घड़ी से मिलाएँ। यह काम हमारा फ्री JWT डिकोडर आपके लिए कर देता है। टोकन पेस्ट करें, और वह एक्सपायर हो गया या एक्सपायर नहीं हुआ दिखाता है, साथ में आपके टाइम ज़ोन और UTC दोनों में सटीक तारीख भी।
यह फ्री है, अकाउंट की ज़रूरत नहीं, और पूरा का पूरा आपके ब्राउज़र में चलता है। 31 अक्टूबर 2026 के हमारे टेस्ट में पेज ने ऐसी कोई रिक्वेस्ट नहीं भेजी जिसमें टोकन हो। मेहमान यूज़र दिन में 5 बार टूल इस्तेमाल कर सकते हैं, और फ्री My Botsy अकाउंट (100% फ्री, कोई स्पैम नहीं) यह रोज़ की सीमा हटा देता है। यहाँ दिए सभी नतीजे असली हैं। डिकोडर वाले नतीजे 31 अक्टूबर 2026 को mybotsy.com पर किए गए टेस्ट से हैं, और लाइब्रेरी वाले उसी दिन PyJWT 2.15.1, jsonwebtoken 9.0.3 और jose 6.2.14 चलाकर निकाले गए।
exp क्लेम का मतलब क्या है
JWT का स्टैंडर्ड RFC 7519 समय से जुड़े तीन क्लेम तय करता है। तीनों वैकल्पिक हैं, और तीनों NumericDate हैं, यानी सेकंड में होते हैं, मिलीसेकंड में नहीं:
- exp (expiration time): इस पल से, और इस पल पर भी, टोकन स्वीकार नहीं किया जाना चाहिए।
- nbf (not before): इस पल से पहले भी टोकन स्वीकार नहीं होना चाहिए।
- iat (issued at): टोकन कब जारी हुआ। यह खुद कुछ अमान्य नहीं करता, पर इससे टोकन की उम्र पता चलती है।
exp और nbf के लिए RFC घड़ियों के फ़र्क (clock skew) की भरपाई के लिए थोड़ी छूट (leeway) की इजाज़त देता है, "आम तौर पर कुछ मिनट से ज़्यादा नहीं"। इसी छूट की वजह से कुछ सेकंड पहले एक्सपायर हुए टोकन पर दो सिस्टम अलग-अलग नतीजा दे सकते हैं।
JWT टोकन एक्सपायर हुआ या नहीं, कैसे चेक करें: स्टेप बाय स्टेप
- टोकन कॉपी करें। यह दो डॉट वाली लंबी स्ट्रिंग होती है, जो अक्सर रिक्वेस्ट हेडर में
Authorization: Bearerके बाद मिलती है, या कुकी या localStorage में सेव रहती है। - इसे JWT डिकोडर में पेस्ट करें। पहले साफ़ करने की ज़रूरत नहीं है। टूल
Authorization:,Bearer, कोटेशन मार्क, स्पेस और लाइन ब्रेक खुद हटा देता है और बता भी देता है कि हटाए गए। - स्थिति (Status) वाली लाइन देखें। यह एक्सपायर हो गया, एक्सपायर नहीं हुआ, अभी मान्य नहीं (जब
nbfभविष्य में हो), कोई एक्सपायरी नहीं (exp नहीं है) या समाप्ति पढ़ी नहीं जा सकती: exp एक मान्य संख्या नहीं है (जबexpमौजूद हो पर संख्या न हो) दिखाती है। - एक्सपायरी (exp) वाली लाइन देखें। इसमें आपके टाइम ज़ोन की तारीख, वही पल UTC में, "कल" या "2 माह में" जैसा सापेक्ष समय, और मूल संख्या, चारों मिलते हैं।
- वैधता अवधि देखें। यह
expमें सेiatघटाकर निकलती है। अगर किसी access token की उम्र 30 दिन है, तो दिक्कत इस एक टोकन में नहीं, बल्कि टोकन जारी करने के तरीके में है। - चेतावनियाँ पढ़ें। डिकोडर मिलीसेकंड वाली तारीखों,
alg: noneऔर पैडिंग वाले टोकन पर चेतावनी देता है। यह भी याद दिलाता है कि सिग्नेचर की जाँच नहीं करता।
हल किए गए उदाहरण (डिकोडर का असली आउटपुट)
ये टेस्ट टोकन हमने HS256 और एक डेमो secret से साइन किए, जिसे बाद में फेंक दिया गया। फिर इन्हें 31 अक्टूबर 2026 को लगभग 15:07 UTC पर mybotsy.com/hi/jwt-decoder में पेस्ट किया। ब्राउज़र भारतीय समय (IST) पर सेट था।
उदाहरण 1: एक्सपायर हो चुका टोकन
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzg4NDEiLCJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJhdWQiOiJvcmRlcnMtYXBpIiwiaWF0IjoxNzkzMzY4ODAwLCJleHAiOjE3OTMzNzI0MDB9.FJV2oXvW0F-Q7x6rzZRKosQG_DhxLQXXz87wW-Ctq60
| लाइन | डिकोडर का आउटपुट |
|---|---|
| स्थिति | एक्सपायर हो गया |
| जारी होने का समय (iat) | शुक्रवार, 30 अक्टूबर 2026 को 7:30:00 pm IST बजे · 2026-10-30T14:00:00Z · कल · 1793368800 |
| एक्सपायरी (exp) | शुक्रवार, 30 अक्टूबर 2026 को 8:30:00 pm IST बजे · 2026-10-30T15:00:00Z · कल · 1793372400 |
| वैधता अवधि | 1 घंटा |
तीनों लाइब्रेरी एकमत थीं। PyJWT ने ExpiredSignatureError: Signature has expired दिया, jsonwebtoken ने expiredAt 2026-10-30T15:00:00.000Z के साथ TokenExpiredError: jwt expired, और jose ने ERR_JWT_EXPIRED।
उदाहरण 2: हेडर समेत पेस्ट किया गया वैध टोकन
हमने पूरी लाइन Authorization: Bearer eyJhbGciOiJIUzI1NiIs… पेस्ट की। डिकोडर ने पहले बताया "डिकोड करने से पहले इनपुट साफ़ किया गया", फिर एक्सपायर नहीं हुआ दिखाया। exp था शुक्रवार, 1 जनवरी 2027 को 5:30:00 am IST, यानी 2027-01-01T00:00:00Z ("2 माह में"), और वैधता अवधि 61 दिन 9 घंटे। गौर करें: UTC की नए साल वाली आधी रात भारत में सुबह 5:30 बजे आती है। IST, UTC से 5 घंटे 30 मिनट आगे है, इसलिए सिर्फ़ कच्ची संख्या देखकर अंदाज़ा लगाने पर तारीख और समय दोनों गलत हो सकते हैं।
उदाहरण 3: अभी मान्य नहीं
nbf 1796083200 और exp 1796169600 वाले टोकन ने अभी मान्य नहीं दिखाया, और मान्य होने का समय था मंगलवार, 1 दिसंबर 2026 को 5:30:00 am IST (2026-12-01T00:00:00Z)। PyJWT ने ImmatureSignatureError दिया और jsonwebtoken ने NotBeforeError: jwt not active। अगर अभी-अभी जारी हुआ टोकन रिजेक्ट हो रहा है, तो एक्सपायरी को दोष देने से पहले nbf और सर्वर की घड़ी जाँचें।
उदाहरण 4: exp है ही नहीं
पेलोड {"sub":"svc-reporting","iat":1790856000} पर कोई एक्सपायरी नहीं (exp नहीं है) आया, और तीनों लाइब्रेरी ने इसे स्वीकार कर लिया। ऐसा टोकन लीक हो जाए तो key बदलने तक काम करता रहेगा। PyJWT में options={"require": ["exp"]} लगाने पर यही टोकन MissingRequiredClaimError: Token is missing the "exp" claim देने लगा।
वे गलतियाँ जो गलत जवाब देती हैं
exp मिलीसेकंड में
सबसे आम गलती है Date.now() को सीधे exp में डाल देना। हमने "exp":1793462400000 वाला टोकन साइन किया। डिकोडर ने चेतावनी दी "exp का मान मिलीसेकंड जैसा लगता है" और उसे मिलीसेकंड मानकर असली तारीख, 31 अक्टूबर 2026 को 16:00 UTC, सही स्थिति और अवधि के साथ दिखाई। jsonwebtoken और jose ने इसे स्वीकार कर लिया, यानी असल में यह कभी एक्सपायर नहीं होगा। PyJWT ने इसे रिजेक्ट किया, पर अपनी iat जाँच की वजह से ("The token is not yet valid (iat)"), exp की वजह से नहीं। हल यह है: टोकन बनाते समय 1000 से भाग दें, और exp से JavaScript Date बनाते समय 1000 से गुणा करें।
exp टेक्स्ट के रूप में
कोटेशन मार्क वाला "exp":"1798761600" स्टैंडर्ड के ख़िलाफ़ है। jsonwebtoken ने इसे invalid exp value कहकर रिजेक्ट किया और jose ने "exp" claim must be a number कहकर। PyJWT ने इसे स्वीकार किया और फिर भी लागू किया: टेक्स्ट में लिखी बीत चुकी तारीख पर उसने ExpiredSignatureError दिया। नतीजा यह कि एक ही टोकन एक सर्विस में चलता है और दूसरी में फेल हो जाता है। डिकोडर इसके मान के साथ लिखता है "मान्य तारीख नहीं: यह सेकंड की संख्या होनी चाहिए।" साथ में एक चेतावनी दिखती है, और स्थिति (Status) वाली लाइन में समाप्ति पढ़ी नहीं जा सकती: exp एक मान्य संख्या नहीं है आता है।
घड़ी का फ़र्क और leeway
हमने एक टोकन बनाया जो 20 सेकंड पहले एक्सपायर हो चुका था। बिना छूट के तीनों लाइब्रेरी ने उसे रिजेक्ट किया। 30 सेकंड की छूट देने पर (PyJWT में leeway=30, jsonwebtoken और jose में clockTolerance: 30) तीनों ने स्वीकार कर लिया। छूट कम रखें, क्योंकि हर अतिरिक्त सेकंड हर टोकन की उम्र बढ़ाता है, चुराए गए टोकन की भी।
base64 --decode से डिकोड करना
JWT में base64url इस्तेमाल होता है, जिसमें + और / की जगह - और _ आते हैं। मशहूर कमांड cut -d. -f2 | base64 --decode | jq .exp तभी तक चलती है जब तक पेलोड में इनमें से कोई अक्षर न आ जाए। GNU coreutils 9.7 पर, - वाले पेलोड ने आधा JSON छापा, फिर base64: invalid input दिया, और jq Unfinished string पर फेल हो गया। पहले tr '_-' '/+' से अक्षर बदल लें, या टोकन सीधे डिकोडर में पेस्ट करें, जो base64url सीधे पढ़ लेता है। Base64 की बाकी दिक्कतों के लिए देखें Base64 कैसे डिकोड करें।
डिकोड करना वेरिफ़ाई करना नहीं है
कोई भी व्यक्ति साल 2100 वाले exp के साथ टोकन बना सकता है। exp पढ़ना डीबगिंग के लिए ठीक है, या ब्राउज़र में यह तय करने के लिए कि टोकन कब रिफ़्रेश करना है। किसी रिक्वेस्ट पर भरोसा करने से पहले सर्वर को सिग्नेचर वेरिफ़ाई करना होगा, और वह भी अनुमत एल्गोरिदम की तय सूची के साथ। RFC 8725 उन हमलों के बारे में बताता है जिनमें एल्गोरिदम बदलकर none कर दिया गया। हमारा डिकोडर alg: none दिखते ही लाल चेतावनी देता है।
कोड में एक्सपायरी कैसे चेक करें
ये फ़ंक्शन तारीख दिखाने या रिफ़्रेश का समय तय करने के लिए हैं, सुरक्षा के लिए नहीं। हमने दोनों को ऊपर वाले टोकन पर चलाकर देखा। एक्सपायर टोकन पर true आया, वैध और base64url टोकन पर false, और बिना exp या टेक्स्ट exp वाले टोकन पर कोई तारीख नहीं आई।
// JavaScript (ब्राउज़र या Node 16+)
function jwtExpiry(token) {
const part = token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');
const { exp } = JSON.parse(atob(part));
if (typeof exp !== 'number') return null; // exp नहीं है, या टेक्स्ट है
return new Date(exp * 1000); // सेकंड -> ms
}
function isExpired(token, leewaySeconds = 0) {
const exp = jwtExpiry(token);
return exp !== null && Date.now() >= exp.getTime() + leewaySeconds * 1000;
}
# Python 3
import base64, json, time
def jwt_exp(token):
seg = token.split(".")[1]
seg += "=" * (-len(seg) % 4) # JWT से हटाई गई पैडिंग वापस जोड़ें
exp = json.loads(base64.urlsafe_b64decode(seg)).get("exp")
return exp if isinstance(exp, (int, float)) else None
def is_expired(token, leeway=0):
exp = jwt_exp(token)
return exp is not None and time.time() >= exp + leeway
तुलना "बड़ा या बराबर" वाली है, क्योंकि RFC के मुताबिक टोकन exp वाले पल पर ही अमान्य हो जाता है। सर्वर पर अपनी लाइब्रेरी के verify फ़ंक्शन पर भरोसा करें (PyJWT में key के साथ jwt.decode, jsonwebtoken में jwt.verify, jose में jwtVerify)। ये सिग्नेचर और तारीखें एक साथ जाँचते हैं।
सुरक्षा की अच्छी आदतें
- चालू टोकन को पासवर्ड की तरह संभालें। एक्सपायर होने तक जिसके पास टोकन है, वह उस यूज़र की तरह काम कर सकता है। टोकन चैट या टिकट में पेस्ट करने के बजाय हमारे जैसा लोकल डिकोडर इस्तेमाल करें।
- Access token कम उम्र के रखें, और सर्वर पर
expअनिवार्य करें। - लंबा, रैंडम HS256 secret इस्तेमाल करें। PyJWT ने चेतावनी दी कि हमारी 20 बाइट की डेमो key "below the minimum recommended length of 32 bytes for SHA256" है। पासवर्ड जनरेटर से बना 64 कैरेक्टर का secret यह सीमा आराम से पार कर लेता है। लंबाई क्यों मायने रखती है, यह हमारी गाइड मज़बूत पासवर्ड कैसे बनाएँ में समझाया गया है।
- पेलोड में कुछ भी गुप्त न रखें। वह सिर्फ़ एन्कोड होता है, और कोई भी उसे Base64 डिकोडर से पढ़ सकता है। डिकोड किया पेलोड JSON की तरह न खुले, तो उसे JSON वैलिडेटर में चलाएँ और पढ़ें invalid JSON कैसे ठीक करें।
सर्टिफ़िकेट भी एक्सपायर होते हैं। अगर "expired" वाली गलती टोकन से नहीं बल्कि HTTPS से आ रही है, तो देखें SSL सर्टिफ़िकेट की एक्सपायरी डेट कैसे चेक करें।
अपना टोकन अभी चेक करें
टोकन को फ्री JWT डिकोडर में पेस्ट करें। यह फ्री है और अकाउंट नहीं माँगता। टोकन आपके ब्राउज़र में ही रहता है, और आपको स्थिति, आपके टाइम ज़ोन और UTC में हर तारीख, और ऊपर बताई हर गलती की चेतावनी मिलती है।
अक्सर पूछे जाने वाले सवाल
मुझे कैसे पता चले कि मेरा JWT कब एक्सपायर होगा?
पेलोड डिकोड करके exp क्लेम पढ़ें, जो 1 जनवरी 1970 (UTC) से बीते सेकंड गिनता है। JavaScript की तारीख बनाने के लिए इसे 1000 से गुणा करें, या टोकन को My Botsy के JWT डिकोडर में पेस्ट करें, जो exp को आपके टाइम ज़ोन और UTC दोनों में दिखाता है।
क्या JWT ठीक exp वाले समय पर एक्सपायर हो जाता है?
हाँ। RFC 7519 कहता है कि exp वाले समय पर और उसके बाद टोकन स्वीकार नहीं होना चाहिए, इसलिए तुलना बड़ा या बराबर से करें। कई सर्वर घड़ी के फ़र्क के लिए कुछ सेकंड की छूट जोड़ते हैं।
डिकोडर टोकन को वैध बताता है, फिर भी सर्वर रिजेक्ट क्यों करता है?
आम वजहें हैं: सर्वर की घड़ी अलग होना, nbf का भविष्य में होना, गलत audience या issuer, या गलत सिग्नेचर। डिकोडर सिर्फ़ तारीखें पढ़ता है, जबकि सर्वर सिग्नेचर और बाकी क्लेम भी जाँचता है।
अगर JWT में exp न हो तो क्या होता है?
ज़्यादातर लाइब्रेरी उसे स्वीकार कर लेती हैं, और टोकन अपने आप कभी एक्सपायर नहीं होता। सर्वर पर exp अनिवार्य करें (जैसे PyJWT में require ऑप्शन से) और access token कम उम्र के रखें।
क्या JWT को ऑनलाइन डिकोडर में पेस्ट करना सुरक्षित है?
सिर्फ़ तब, जब डिकोडर लोकल चलता हो। My Botsy का डिकोडर आपके ब्राउज़र में डिकोड करता है, और टोकन कभी हमारे सर्वर पर नहीं भेजा जाता। फिर भी हर चालू टोकन को पासवर्ड की तरह संभालें, और उदाहरण शेयर करते समय एक्सपायर हो चुके या टेस्ट टोकन इस्तेमाल करें।
क्या My Botsy का JWT डिकोडर फ्री है?
हाँ। यह फ्री है, अकाउंट नहीं माँगता और आपके ब्राउज़र में चलता है। मेहमान यूज़र दिन में 5 बार इस्तेमाल कर सकते हैं, और फ्री अकाउंट यह सीमा हटा देता है।