JWT टोकन को कैसे डीकोड और निरीक्षण करें
JSON Web Tokens (JWTs) आधुनिक वेब अनुप्रयोगों में प्रमाणीकरण को संभालने का सबसे सामान्य तरीका है। जब auth के साथ कुछ गलत हो जाता है, एक उपयोगकर्ता अप्रत्याशित रूप से लॉग आउट हो जाता है, अनुमतियाँ गलत हैं, एक API 401 लौटाता है, JWT को डीकोड करना आमतौर पर पहला डीबगिंग कदम है। JWT के तीन भागों, मानक दावों, उन एल्गोरिथम जिनसे यह हस्ताक्षरित किया जा सकता है, और सामान्य चूकों को समझना auth डीबगिंग को वूडू से एक नियमित जाँच में बदल देता है।
JWT का संक्षिप्त इतिहास
JWTs मई 2015 में RFC 7519 में मानकीकृत किए गए, IETF में कई वर्षों के ड्राफ्ट पुनरावृत्ति के बाद। प्रारूप ने पहले के संक्षिप्त-टोकन डिज़ाइनों (SAML अभिकथन, सरल अपारदर्शी कुकीज़) से उधार लिया लेकिन उन्हें जो कमी थी वह दो चीजें जोड़ीं: एक कड़ी JSON आकृति जो किसी भी भाषा में पठनीय थी, और एक base64url-सुरक्षित एन्कोडिंग जो URL मापदंडों, HTTP हेडर, और फॉर्म फील्ड में बिना री-एस्केप के जीवित रहती थी। सहायक विनिर्देश, हस्ताक्षरों के लिए JWS (RFC 7515), एन्क्रिप्शन के लिए JWE (RFC 7516), और एल्गोरिथम नामों के लिए JWA (RFC 7518), मिलकर JOSE (JavaScript Object Signing and Encryption) परिवार बनाते हैं।
OAuth 2.0 और OpenID Connect ने जल्द ही JWT को अपने डिफ़ॉल्ट टोकन प्रारूप के रूप में अपनाया, यही कारण है कि लगभग हर आधुनिक auth प्रदाता (Auth0, Okta, Cognito, Keycloak, Firebase, Supabase, Clerk) आज इन्हें जारी करते हैं। स्व-समाहित टोकन और स्टेटलेस बैकएंड का संयोजन माइक्रोसर्विसेज और API गेटवे के लिए बहुत स्वाभाविक फिट निकला। नुकसान यह है कि JWTs को दुरुपयोग करना कुख्यात रूप से आसान है, और पिछले दशक ने उन पुस्तकालयों में CVE की एक स्थिर धारा का निर्माण किया जिन्होंने एल्गोरिथम को सावधानी से मान्य नहीं किया।
JWT के अंदर क्या है
JWT के तीन भाग होते हैं, बिंदुओं द्वारा अलग किए गए:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U
हेडर: एल्गोरिथम (HS256, RS256, आदि) और टोकन प्रकार शामिल है।
{"alg": "HS256", "typ": "JWT"}
पेलोड: उपयोगकर्ता और टोकन के बारे में दावे (डेटा अभिकथन) शामिल हैं।
{"sub": "1234567890", "name": "Alice", "exp": 1700000000}
हस्ताक्षर, एक क्रिप्टोग्राफ़िक हैश जो सत्यापित करता है कि टोकन के साथ छेड़छाड़ नहीं की गई है। हस्ताक्षर कुंजी के बिना आप इसे नहीं पढ़ सकते।
हर अनुभाग base64url-एन्कोडेड है, जिसका अर्थ है कि यह + और / के बजाय - और _ का उपयोग करता है और अंतिम = पैडिंग छोड़ देता है। Base64url एन्क्रिप्शन नहीं है; बस मध्य खंड को किसी भी डिकोडर में चिपकाने से पेलोड प्रकट हो जाता है। यह डिज़ाइन के अनुसार है: मध्य खंडों को रास्ते में सेवाओं द्वारा पठनीय होने के लिए डिज़ाइन किया गया है, हस्ताक्षर ही एकमात्र भाग है जो प्रामाणिकता सिद्ध करता है।
सामान्य JWT दावे
मानक दावे IANA के साथ पंजीकृत हैं और RFC 7519 में परिभाषित हैं। अधिकांश वैकल्पिक हैं, पर नीचे दिए गए लगभग हमेशा मौजूद होते हैं।
| दावा | पूरा नाम | क्या समाहित है |
|---|---|---|
sub | Subject | उपयोगकर्ता ID या पहचानकर्ता |
exp | Expiration | Unix टाइमस्टैम्प जब टोकन समाप्त होता है |
iat | Issued At | Unix टाइमस्टैम्प जब टोकन बनाया गया |
iss | Issuer | किसने टोकन बनाया (आपका auth सर्वर) |
aud | Audience | टोकन किसके लिए है |
nbf | Not Before | टोकन इस समय से पहले मान्य नहीं |
jti | JWT ID | टोकन के लिए अद्वितीय पहचानकर्ता |
azp | Authorized Party | जिस पार्टी को टोकन जारी किया गया (OIDC) |
scope / scp | OAuth स्कोप | दी गई अनुमतियाँ, अक्सर स्पेस-सेपरेटेड |
email | ईमेल | मानक OIDC उपयोगकर्ता पहचानकर्ता |
name | नाम | प्रदर्शन नाम (OIDC) |
nonce | Nonce | OIDC पुनः-प्रसारण-सुरक्षा मान |
kid (हेडर) | Key ID | कौन सी हस्ताक्षर कुंजी उपयोग की गई (JWKS लुकअप के लिए) |
मानक सेट से परे, अनुप्रयोग अपने स्वयं के कस्टम दावे जोड़ते हैं (roles, tenant_id, feature_flags, permissions)। कस्टम दावा नाम डिफ़ॉल्ट रूप से नेमस्पेस नहीं होते, जिसका अर्थ है कि दो अलग-अलग सेवाएँ एक ही नाम का उपयोग अलग-अलग चीज़ों के लिए कर सकती हैं; एक URI (https://myapp.com/roles) के साथ उपसर्ग देने की OIDC परंपरा टकराव से बचाती है।
JWT को कैसे डीकोड करें
- अपना टोकन चिपकाएँ: डिकोडर में पूरा JWT (header.payload.signature प्रारूप) दर्ज करें। ब्राउज़र-आधारित डिकोडर इसे स्थानीय रूप से संसाधित करते हैं, टोकन कभी पृष्ठ नहीं छोड़ता।
- डीकोडेड अनुभाग देखें: उपकरण हेडर (एल्गोरिथम), पेलोड (दावे), और हस्ताक्षर को स्वरूपित JSON के रूप में दिखाता है, टाइमस्टैम्प Unix पूर्णांकों और मानव-पठनीय तिथियों दोनों के रूप में दिखाए जाते हैं।
- दावे जाँचें: समाप्ति समय, जारीकर्ता, सब्जेक्ट, ऑडियंस, और कोई भी कस्टम दावा जो आपके प्राधिकरण तर्क को चलाता है, का परीक्षण करें।
- अपेक्षाओं से तुलना करें: जारीकर्ता को कॉन्फ़िगर किए गए auth प्रदाता के साथ क्रॉस-रेफरेंस करें, ऑडियंस को उस API के साथ जिसे टोकन भेजा जा रहा है, और किसी भी रोल/स्कोप दावे को उन अनुमतियों के साथ जो उपयोगकर्ता के पास होनी चाहिए।
- समय-यात्रा परीक्षण:
iat,nbf, औरexpपर होवर करें यह देखने के लिए कि टोकन वर्तमान में मान्य है, जल्द ही समाप्त होगा, या इतने समय पहले जारी किया गया था कि आपकी घड़ी विचलन सहनशीलता अब इसे कवर नहीं करती।
हस्ताक्षर एल्गोरिथम
सभी JWT एक ही क्रिप्टो का उपयोग नहीं करते। alg हेडर आपको बताता है कि हस्ताक्षर किस परिवार से संबंधित है, और प्रत्येक की बहुत अलग सुरक्षा विशेषताएँ हैं।
| एल्गोरिथम | परिवार | कुंजी प्रकार | कब चुनें |
|---|---|---|---|
HS256 | HMAC | साझा गुप्त | एकल-सेवा ऐप्स; कभी भी टीमों के बीच गुप्त साझा न करें |
HS384 / HS512 | HMAC | साझा गुप्त | HS256 के समान लंबे डाइजेस्ट के साथ |
RS256 | RSA | सार्वजनिक/निजी कुंजी जोड़ी | OIDC के लिए सबसे सामान्य; सत्यापनकर्ता को केवल सार्वजनिक कुंजी चाहिए |
RS384 / RS512 | RSA | कुंजी जोड़ी | RS256 के समान बड़ी कुंजी के साथ |
PS256 / PS384 / PS512 | RSA-PSS | कुंजी जोड़ी | आधुनिक RSA, नए परिनियोजन के लिए RS पर अनुशंसित |
ES256 / ES384 / ES512 | ECDSA | दीर्घवृत्तीय-वक्र कुंजी जोड़ी | RSA से छोटी कुंजी, तेज़ सत्यापन |
EdDSA | Ed25519 | Edwards-वक्र कुंजी जोड़ी | नवीनतम, सबसे छोटा, सबसे तेज़; अभी तक सार्वभौमिक नहीं |
none | कोई नहीं | कोई नहीं | उत्पादन में निषिद्ध; कुछ पुराने पुस्तकालय अभी भी स्वीकार करते हैं |
असममित एल्गोरिथम (RS*, PS*, ES*, EdDSA) किसी भी सेवा को केवल एक सार्वजनिक कुंजी के साथ एक टोकन को सत्यापित करने देते हैं, यही कारण है कि वे OIDC पर प्रभुत्व रखते हैं। सममित (HS*) एक अनुप्रयोग के अंदर ठीक है पर कई उपभोक्ताओं के बीच घुमाना या वितरित करना दुःस्वप्न बन जाता है।
JWT के साथ डीबगिंग
टोकन समाप्त? exp दावा जाँचें। Unix टाइमस्टैम्प को मानव-पठनीय तिथि में बदलें। यदि यह अतीत में है, तो टोकन समाप्त हो गया है और इसे ताज़ा करने की आवश्यकता है। अधिकांश JWT पुस्तकालय डिफ़ॉल्ट रूप से समाप्त टोकन अस्वीकार करते हैं; यदि आपका ऐप इन्हें स्वीकार करता है, तो यह एक सुरक्षा बग है।
गलत अनुमतियाँ? पेलोड में रोल या स्कोप दावे खोजें। ये कार्यान्वयन से भिन्न होते हैं पर अक्सर "role": "admin" या "scope": "read write profile" जैसे दिखते हैं।
उपयोगकर्ता पहचान समस्याएँ? sub दावा उपयोगकर्ता की पहचान करता है। सत्यापित करें कि यह अपेक्षित उपयोगकर्ता ID से मेल खाता है। ध्यान दें कि कुछ प्रदाता अपारदर्शी GUID का उपयोग करते हैं जबकि अन्य ईमेल पतों का; डिकोडर आपको ठीक वही दिखाता है जो वहाँ है।
टोकन स्वीकार नहीं? aud (ऑडियंस) दावा जाँचें। यदि API एक विशिष्ट ऑडियंस मान की अपेक्षा करता है और टोकन में एक अलग है, तो इसे अस्वीकार किया जाएगा। ऑडियंस बेमेल टोकन को गलत सेवा पर रूट करने का एक सामान्य लक्षण है।
परिनियोजन के बाद 401 त्रुटियाँ? iss (जारीकर्ता) दावा जाँचें। एक नया auth-प्रदाता टेनेंट या स्विच-आउट हस्ताक्षर कुंजी जारीकर्ता URL बदल देती है; यदि आपका सत्यापनकर्ता अभी भी पुराने पर भरोसा करता है, तो हर टोकन अमान्य दिखता है।
घड़ी विचलन समस्याएँ? यदि iat थोड़ा भविष्य में है या exp थोड़ा अतीत में, तो आपके सर्वर की घड़ी विचलित हो सकती है। अधिकांश JWT पुस्तकालय कुछ सेकंड की छूट की अनुमति देते हैं; यदि नहीं, NTP-सिंक्रनाइज़ की गई घड़ी समस्या ठीक करती है।
सामान्य चूकें
- अनुमति-सूची के बिना
algहेडर पर भरोसा, क्लासिक JWT भेद्यता थी एक सर्वर जो भी एल्गोरिथम टोकन कहता था वह स्वीकार करता था।alg: none(कोई हस्ताक्षर नहीं) याalg: HS256(आपकी सार्वजनिक कुंजी को गुप्त के रूप में हस्ताक्षरित) वाला टोकन किसी भी पेलोड को जाली कर सकता था। सत्यापनकर्ता को सटीक अपेक्षित एल्गोरिथम पर पिन करें। - पेलोड में रहस्य रखना, पेलोड base64url-एन्कोडेड है, एन्क्रिप्टेड नहीं। टोकन वाला कोई भी इसे पढ़ सकता है। पासवर्ड, API कुंजियाँ, या कुछ भी ऐसा कभी न शामिल करें जिसे आप क्वेरी स्ट्रिंग में नहीं रखेंगे।
- रद्दीकरण के बिना दीर्घजीवी टोकन, 30-दिन का JWT बिना टोकन ब्लैकलिस्ट या सत्र स्टोर के रद्द नहीं किया जा सकता। एक्सेस टोकन छोटा रखें (5-60 मिनट) और लंबे सत्रों के लिए रिफ्रेश-टोकन फ्लो का उपयोग करें।
- घड़ी विचलन भूलना, विभिन्न समय क्षेत्रों या विचलित घड़ियों वाले सर्वर ऐसे टोकन को अस्वीकार करते हैं जो मान्य होने चाहिए।
expऔरnbfपर 30-60 सेकंड की छूट दें। - सत्यापन के बिना जारीकर्ता पर भरोसा,
issदावा पेलोड का हिस्सा है जिसे कोई भी लिख सकता है। इसका मान कॉन्फ़िगर किए गए जारीकर्ता से मेल खाता है यह सत्यापित करना आवश्यक है; इसे अनुमति-सूचीबद्ध करना एक हमलावर को आपके प्रदाता से आने का दावा करने वाले टोकन गढ़ने से रोकता है। - परिवेशों में HS256 गुप्त का पुन: उपयोग, dev और prod में एक ही गुप्त का अर्थ है कि एक लीक हुआ dev टोकन उत्पादन में काम करता है। प्रति-परिवेश कुंजियाँ उपयोग करें, आदर्श रूप से एक गुप्त प्रबंधक से लाई गई।
- localStorage में टोकन संग्रहीत करना, localStorage किसी भी JavaScript द्वारा पठनीय है, इसलिए एक एकल XSS बग हर उपयोगकर्ता के टोकन को बाहर निकाल देता है। SameSite=Lax (या Strict) के साथ HttpOnly कुकीज़ सुरक्षित डिफ़ॉल्ट हैं।
- पूर्ण टोकन लॉग करना, पूर्ण JWT को कैप्चर करने वाले अनुप्रयोग लॉग टोकन को लॉग एक्सेस वाले किसी भी व्यक्ति को लीक करते हैं। पहले 10 वर्णों में काटें या केवल
jtiलॉग करें। kidरोटेशन की उपेक्षा, जब एक प्रदाता हस्ताक्षर कुंजियाँ घुमाता है, तो नए टोकन में एक नयाkidहेडर होता है। एक सत्यापनकर्ता जो JWKS को हमेशा के लिए कैश करता है वह वैध टोकन अस्वीकार करना शुरू कर देगा। key-id गुम पर JWKS को फिर से लाएँ।- JWT को सत्रों के साथ असंगत रूप से मिलाना, कुछ एंडपॉइंट JWT के पीछे, अन्य कुकी सत्रों के पीछे, ऐसे बग्स की ओर ले जाते हैं जहाँ एक लॉग-इन उपयोगकर्ता एक मार्ग पर अप्रमाणित दिखाई देता है। प्रति सेवा एक मॉडल चुनें।
JWT के विकल्प
JWT प्रभुत्वशाली है पर एकमात्र विकल्प नहीं। प्रत्येक विकल्प विभिन्न गुणों का व्यापार करता है।
| तंत्र | ताकत | कमज़ोरी |
|---|---|---|
| JWT (JWS) | स्व-समाहित, सेवाओं के पार आसान | अतिरिक्त राज्य के बिना रद्द नहीं किया जा सकता |
| अपारदर्शी टोकन + अंतर्दृष्टि | रद्द करना आसान, दावे छुपाता है | हर अनुरोध auth सर्वर को छूता है |
| सर्वर-साइड सत्र | सबसे सरल मॉडल, तत्काल रद्दीकरण | सेवाओं के पार स्केल करना कठिन |
| PASETO | सुरक्षित JWT प्रतिस्थापन (कोई alg भ्रम नहीं) | छोटा पारिस्थितिकी तंत्र |
| Macaroons | अंतर्निहित क्षीणन (प्रत्यायोजित अधिकार) | सीमित पुस्तकालय समर्थन |
| OAuth 2.0 + JWT एक्सेस टोकन | API के लिए उद्योग मानक | विनिर्देश बड़ा, गलत-कार्यान्वित करना आसान |
| OIDC ID टोकन | मानक उपयोगकर्ता पहचान + JWT | अक्सर एक्सेस टोकन के साथ भ्रमित |
| mTLS क्लाइंट प्रमाणपत्र | परिवहन परत पर सबसे मज़बूत auth | प्रमाणपत्र प्रबंधन का ओवरहेड |
अधिकांश टीमों के लिए, विकल्प JWT और अपारदर्शी टोकन के बीच है। JWT तब जीतता है जब सत्यापन सस्ता और ऑफ़लाइन होना चाहिए; अपारदर्शी टोकन तब जीतते हैं जब रद्दीकरण तात्कालिक होना चाहिए।
गोपनीयता और डिकोडर
JWT डिकोडर पूरी तरह से आपके ब्राउज़र में चलता है। आप जो टोकन चिपकाते हैं वह विभाजित होता है, base64url-डीकोड होता है, और JSON बिना किसी नेटवर्क अनुरोध के पार्स और सुंदर-मुद्रित होता है। डीकोड किए गए टोकनों का कोई लॉग नहीं है, उनमें मौजूद दावों पर कोई विश्लेषण नहीं, और किसी के लिए भी यह पुनर्निर्माण करने का कोई तरीका नहीं कि आप किसके लिए डीबग कर रहे थे। JWTs में अक्सर उपयोगकर्ता पहचानकर्ता, ईमेल पते, आंतरिक रोल नाम, और टेनेंट ID होते हैं, ठीक वह प्रकार का मेटाडेटा जिसे आप किसी अजनबी के सर्वर पर भेजना नहीं चाहेंगे। क्लाइंट-साइड डीकोड करना उस जानकारी को आपकी मशीन पर रखता है, जो प्रमाणीकरण को छूने वाले किसी भी डीबगिंग कार्य के लिए सही डिफ़ॉल्ट है।
अक्सर पूछे जाने वाले प्रश्न
क्या मैं डीकोडर के साथ JWT हस्ताक्षर सत्यापित कर सकता हूँ?
नहीं। हस्ताक्षर सत्यापन के लिए हस्ताक्षर रहस्य या सार्वजनिक कुंजी की आवश्यकता होती है, जो आपके सर्वर पर रखी जाती है। एक डीकोडर आपको दिखाता है कि टोकन में क्या है, लेकिन क्रिप्टोग्राफ़िक सत्यापन आपके बैकएंड पर होना चाहिए। प्रोडक्शन में असत्यापित JWT पर कभी भरोसा न करें।
क्या किसी ऑनलाइन टूल में JWT पेस्ट करना सुरक्षित है?
हाँ, जब टूल आपके ब्राउज़र में चलता है। ब्राउज़र डीकोडर टोकन को स्थानीय रूप से प्रोसेस करते हैं, कुछ भी सर्वर पर नहीं भेजा जाता। उन टूल्स से बचें जो आपके टोकन के साथ नेटवर्क अनुरोध करते हैं।
exp क्लेम क्या है?
exp (समाप्ति) क्लेम एक Unix टाइमस्टैम्प है जो इंगित करता है कि टोकन कब समाप्त होता है। इस तिथि के बाद, टोकन को अस्वीकार किया जाना चाहिए। प्रमाणीकरण समस्याओं को डिबग करने के लिए हमेशा इस क्लेम की जाँच करें।
क्या JWT एन्क्रिप्ट किए जा सकते हैं?
मानक JWT (JWS) हस्ताक्षरित हैं लेकिन एन्क्रिप्टेड नहीं हैं, कोई भी पेलोड को डीकोड कर सकता है। JWE (JSON Web Encryption) टोकन एन्क्रिप्टेड हैं, लेकिन कम सामान्य हैं। मानक JWT पेलोड में कभी संवेदनशील डेटा (पासवर्ड, रहस्य) न डालें।
What is the alg none vulnerability?
Early JWT libraries accepted tokens with an alg header set to "none", meaning the signature could be omitted entirely. An attacker who set this header could forge any payload. Modern libraries reject "none" by default, but legacy systems may still be exposed; always allow-list the expected algorithm rather than trusting the header.
How should I store a JWT on the client?
HttpOnly secure cookies with SameSite=Lax (or Strict) are the safest default; they cannot be read by JavaScript, which mitigates XSS token theft. localStorage is convenient but vulnerable to any XSS bug. Never store long-lived JWTs alongside untrusted scripts.