JWT डिकोडर

टोकन का हेडर और क्लेम पढ़ें और देखें कि वह अपने बारे में क्या कहता है। डिकोडिंग, वेरिफ़िकेशन नहीं।

डिकोड करना जाँचना नहीं है। JWT के दो पढ़े जा सकने वाले खंड महज़ base64 हैं — इन्हें कोई भी पढ़ सकता है और कोई भी लिख सकता है। टोकन पर भरोसा सिर्फ़ हस्ताक्षर से बनता है, और उसे जाँचने के लिए कुंजी चाहिए। इस पेज के पास कुंजी नहीं है, वह माँगता भी नहीं, और यह दावा भी नहीं करता कि टोकन असली है या नहीं।

शुरू में लगा «Bearer» अपने आप हटा दिया जाता है। आप जो चिपकाते हैं, वह इस पेज से बाहर नहीं जाता।

तीन हिस्से, जिनमें से एक ही मायने रखता है

JWT बिंदुओं से जुड़ी तीन base64url स्ट्रिंग है। पहले दो ऐसा JSON हैं जिन्हें आप पढ़ सकते हैं; तीसरा पहले दो पर किया गया हस्ताक्षर है।

eyJhbGciOiJIUzI1NiJ9  .  eyJzdWIiOiIxMjM0In0  .  4fXK...
      header                    payload            signature

हेडर बताता है कि उस पर किस एल्गोरिद्म से हस्ताक्षर हुआ। पेलोड क्लेम ढोता है। इनमें से कोई भी एन्क्रिप्टेड नहीं है — base64 ट्रांसपोर्ट एन्कोडिंग है, छिपाव नहीं, और टोकन रखने वाला कोई भी इंसान दोनों हिस्से क़रीब एक सेकंड में पढ़ लेता है।

सुरक्षा का काम सिर्फ़ हस्ताक्षर करता है। वह साबित करता है कि पहले दो हिस्से किसी ऐसे ने बनाए जिसके पास साइनिंग कुंजी थी, और उसके बाद उन्हें बदला नहीं गया। उसे जाँचे बिना JWT बस एक अपने बारे में ख़ुद बताने वाली टेक्स्ट फ़ाइल है, जिसका अधिकार क्लाइंट की भेजी किसी भी दूसरी स्ट्रिंग से ज़्यादा नहीं।

इसीलिए यह पेज आपको यह नहीं बताएगा कि टोकन वैध है

सत्यापन के लिए कुंजी चाहिए, और «अपना साइनिंग सीक्रेट किसी वेब पेज में चिपकाइए» — इस बात का कोई भी रूप अच्छी सलाह नहीं है। इसके बजाय यह टूल वह बताता है जो टोकन ख़ुद अपने बारे में कहता है: उसकी मियाद ख़त्म हुई या नहीं, उसका शुरू होने का वक़्त आया या नहीं, एल्गोरिद्म सममित है या असममित, और क्या वह दावा करता है कि उसे हस्ताक्षर की ज़रूरत ही नहीं।

alg:none, और यह सिखाने वाला मामला क्यों है

विनिर्देश "alg": "none" की इजाज़त देता है — यानी बिना हस्ताक्षर वाला टोकन। हमला ख़ुद ही लिख जाता है: कोई जायज़ टोकन लीजिए, पेलोड में जो चाहे दावा कर दीजिए, एल्गोरिद्म none कर दीजिए, हस्ताक्षर मिटा दीजिए, और भेज दीजिए।

जो लाइब्रेरी हेडर से एल्गोरिद्म पढ़कर वैसा ही करती है, वह इसे मान लेगी। सत्यापन की नीति हमलावर ने चुनी, क्योंकि वह नीति संदेश के उसी हिस्से में थी जो हमलावर के क़ब्ज़े में था।

इससे जुड़ा दूसरा रूप है एल्गोरिद्म कन्फ़्यूज़न। RS256 से सत्यापन करने वाले सर्वर के पास सार्वजनिक कुंजी होती है, और वह गोपनीय नहीं होती। हेडर को HS256 — एक सममित एल्गोरिद्म — कर दीजिए और उसी सार्वजनिक कुंजी को साझा सीक्रेट मानकर हस्ताक्षर कर दीजिए। भोली लाइब्रेरी दोनों के लिए वही कुंजी-सामग्री इस्तेमाल कर लेती है, और गढ़ा हुआ टोकन सत्यापित हो जाता है।

दोनों का इलाज एक ही है, और यह आम सिद्धांत कहीं और भी साथ ले जाने लायक़ है: सत्यापन करने वाला ख़ुद बताए कि वह कौन-से एल्गोरिद्म स्वीकार करता है, टोकन से पूछे नहीं।

प्रोडक्शन में असल में क्या बिगड़ता है

लक्षणआम वजह
जारी होते ही अस्वीकारघड़ी का अंतर। iat या nbf सत्यापक की घड़ी से कुछ सेकंड आगे है। थोड़ी छूट रखिए।
लोकल पर चलता है, तैनात होने पर नहींहर परिवेश की साइनिंग कुंजी अलग — स्टेजिंग का टोकन प्रोडक्शन पर भेज दिया गया।
हस्ताक्षर वैध, फिर भी अस्वीकारaud या iss क्लेम उस सेवा की अपेक्षा से मेल नहीं खाता।
चलता है, फिर बीच सेशन में रुक जाता हैमियाद। छोटी उम्र वाले टोकन को रिफ़्रेश की व्यवस्था चाहिए, और आम तौर पर वही कड़ी ग़ायब होती है।
हेडर बहुत बड़े होने से रिक्वेस्ट नाकामटोकन सीमा से बड़ा हो गया। ज़्यादातर सर्वर हेडर की सीमा क़रीब 8 KB रखते हैं, और ब्राउज़र एक कुकी की 4 KB।

रद्द करने की समस्या

JWT इस्तेमाल करने की वजह यही है कि सत्यापन के लिए डेटाबेस देखना नहीं पड़ता — टोकन अपना सबूत ख़ुद ढोता है। और ठीक इसी वजह से आप उसे रद्द नहीं कर सकते। सत्यापन के वक़्त कुछ देखा ही नहीं जाता, इसलिए यह दर्ज करने की कोई जगह ही नहीं कि अमुक टोकन अब काम करना बंद कर दे।

विकल्प, और कोई भी मुफ़्त नहीं:

  • छोटी मियाद और साथ में रिफ़्रेश टोकन। मानक जवाब। एक्सेस टोकन कुछ मिनट जीते हैं, रिफ़्रेश टोकन डेटाबेस से मिलाए जाते हैं और रद्द किए जा सकते हैं।
  • एक डिनाई-लिस्ट। हर टोकन के jti को रद्द किए गए टोकनों के भंडार से मिलाइए — जिससे वही डेटाबेस-फेरा लौट आता है जिससे बचने के लिए यह फ़ॉर्मैट बना था।
  • साइनिंग कुंजी बदल दीजिए। एक झटके में हर टोकन अमान्य, बाक़ी सबके भी।

अगर अलग-अलग सेशनों को तुरंत रद्द कर पाने की ज़रूरत आपके लिए स्टेटलेस सत्यापन से बड़ी है, तो भंडार के सहारे चलने वाला अपारदर्शी सेशन पहचानकर्ता कहीं सरल डिज़ाइन है — और उसे कम आँका जाता है।

संबंधित

तीनों हिस्से बिना पैडिंग वाले URL-सेफ़ Base64 हैं — इसीलिए कोई हिस्सा सख़्त डिकोडर में अक्सर नाकाम रहता है। डिकोड होने के बाद दोनों पढ़े जा सकने वाले हिस्से JSON होते हैं। और यह टोकन जिस प्रमाण-पत्र की जगह खड़ा है, उसके लिए स्ट्रेंथ चेकर लॉगिन के दूसरे सिरे को सँभालता है।

JWT से जुड़े सवाल

क्या JWT को डिकोड करने से वह सत्यापित हो जाता है?

नहीं, और यही फ़र्क़ पूरा सुरक्षा मॉडल है। हेडर और पेलोड base64url में हैं — उन्हें पढ़ने के लिए कुछ नहीं चाहिए। सत्यापन का मतलब है कुंजी से हस्ताक्षर दोबारा गिनना और मिलाना, जो साबित करता है कि टोकन उसी ने जारी किया जिसके पास वह कुंजी है और उसके बाद उसे बदला नहीं गया। बिना कुंजी वाला डिकोडर बता सकता है कि टोकन क्या दावा करता है; उस पर भरोसा करना चाहिए या नहीं, यह सिर्फ़ सत्यापन बताता है।

क्या किसी वेबसाइट पर असली टोकन चिपकाना सुरक्षित है?

इस पेज पर हाँ — डिकोडिंग आपके ब्राउज़र में होती है और कुछ भी भेजा नहीं जाता। पर सवाल के पीछे की सहज आशंका अच्छी है और उसे बनाए रखना चाहिए। JWT आम तौर पर एक जीवित प्रमाण-पत्र होता है: जब तक वह ख़त्म न हो, जिसके पास है वह आपकी जगह काम कर सकता है। जो डिकोडर उसे सर्वर पर भेजता है, उसे एक चालू सेशन थमा दिया गया। प्रोडक्शन का टोकन चिपकाने से पहले देखिए कि टूल अपना काम कहाँ करता है।

क्या मैं JWT के पेलोड में राज़ रख सकता हूँ?

नहीं। पेलोड पर हस्ताक्षर होता है, एन्क्रिप्शन नहीं — जिसके पास टोकन है वह उसे पढ़ सकता है, उस उपयोगकर्ता समेत जिसे वह जारी हुआ। हस्ताक्षर इतना पक्का करता है कि सामग्री बदली नहीं गई; उसे छिपाने में उसका कोई योगदान नहीं। अगर आपको सचमुच गोपनीय पेलोड चाहिए तो वह JWE है — एक अलग और कहीं ज़्यादा जटिल विनिर्देश। व्यवहार में बेहतर जवाब आम तौर पर यही होता है कि संवेदनशील हिस्सा सर्वर पर रखिए और टोकन में सिर्फ़ एक पहचानकर्ता।

alg:none कमज़ोरी क्या है?

JWT विनिर्देश «alg» के तौर पर «none» की इजाज़त देता है, यानी बिना हस्ताक्षर वाला टोकन। हमला यह है कि कोई वैध टोकन लीजिए, पेलोड बदलकर ख़ुद को एडमिन बताइए, alg को none कर दीजिए और हस्ताक्षर हटा दीजिए। जो लाइब्रेरी हेडर के एल्गोरिद्म फ़ील्ड पर भरोसा करती है वह उसे वैध मान लेगी — टोकन ने ही तो कह दिया था कि जाँच की ज़रूरत नहीं। हर बड़ी लाइब्रेरी में यह ठीक किया जा चुका है, पर सबक़ आम है: कौन-से एल्गोरिद्म स्वीकार होंगे, यह सर्वर तय करे, टोकन नहीं।

समय से पहले JWT को रद्द कैसे करूँ?

ज़्यादातर कर ही नहीं सकते, और यही सौदा इस फ़ॉर्मैट ने किया है। JWT बिना डेटाबेस देखे सत्यापित हो जाता है, इसीलिए वह तेज़ है — और इसीलिए सत्यापन के वक़्त जो कुछ देखा जाता है उसमें से किसी को पता ही नहीं कि आप उसे रद्द करना चाहते थे। काम चलने वाले जवाब हैं: छोटी अवधि और साथ में रिफ़्रेश टोकन; रद्द किए गए पहचानकर्ताओं की सूची जो हर रिक्वेस्ट पर जाँची जाए (जिससे वही डेटाबेस-फेरा लौट आता है जिससे आप बच रहे थे); या साइनिंग कुंजी बदल देना, जिससे सब एक साथ अमान्य हो जाए।

मेरा टोकन वैध दिखता है फिर भी अस्वीकार क्यों हो रहा है?

मियाद ख़त्म होने के अलावा आम वजहें हैं: जारी करने वाले और जाँचने वाले की घड़ियों में अंतर; ऑडियंस या इशुअर का दावा जो सर्वर की अपेक्षा से मेल नहीं खाता; या टोकन का उस कुंजी से हस्ताक्षरित होना जो जाँचने वाले के पास नहीं है — अक्सर स्टेजिंग का टोकन प्रोडक्शन पर चला देना। ऊपर वाला डिकोडर समय से जुड़ी वे गड़बड़ियाँ बता देता है जो उसे दिख सकती हैं; ऑडियंस और कुंजी के बेमेल के बारे में सिर्फ़ सर्वर ही बता सकता है।

अंतिम समीक्षा । कुछ पुराना पड़ा हुआ मिला? हमें बताइए.