JWT (JSON वेब टोकन) समाप्ति की स्वचालित लम्बी अवधि


509

मैं JWT- आधारित प्रमाणीकरण को हमारे नए REST API पर लागू करना चाहूंगा। लेकिन चूंकि समाप्ति टोकन में सेट है, तो क्या इसे स्वचालित रूप से लम्बा करना संभव है? मैं नहीं चाहता कि उपयोगकर्ता हर X मिनट के बाद साइन इन करें, यदि वे उस अवधि में एप्लिकेशन का सक्रिय रूप से उपयोग कर रहे थे। यह एक बड़ा UX विफल होगा।

लेकिन समय सीमा समाप्त होने से एक नया टोकन बनता है (और यह समाप्त होने तक पुराना अभी भी वैध है)। और प्रत्येक अनुरोध के बाद एक नया टोकन बनाना मेरे लिए मूर्खतापूर्ण लगता है। जब एक से अधिक टोकन एक ही समय में मान्य हों, तो सुरक्षा समस्या जैसा लगता है। बेशक मैं एक ब्लैकलिस्ट का उपयोग कर पुराने इस्तेमाल को अमान्य कर सकता हूं लेकिन मुझे टोकन स्टोर करने की आवश्यकता होगी। और JWT के लाभों में से एक भंडारण नहीं है।

मैंने पाया कि कैसे Auth0 ने इसे हल किया। वे न केवल JWT टोकन बल्कि एक ताज़ा टोकन का उपयोग करते हैं: https://docs.auth0.com/refresh-token

लेकिन फिर, इसे (Auth0 के बिना) लागू करने के लिए मुझे ताज़ा टोकन स्टोर करने और उनकी समाप्ति बनाए रखने की आवश्यकता होगी। फिर असली फायदा क्या है? केवल एक टोकन क्यों नहीं है (JWT नहीं) और सर्वर पर समाप्ति को बनाए रखें?

क्या अन्य विकल्प हैं? क्या JWT का उपयोग इस परिदृश्य के लिए अनुकूल नहीं है?


1
वास्तव में एक साथ कई वैध टोकन के साथ कोई सुरक्षा मुद्दा नहीं है ... वास्तव में वैध टोकन की अनंत संख्या है ... तो, फिर एक ताज़ा टोकन क्यों है? मैं उन्हें प्रत्येक अनुरोध के बाद पुनर्जीवित करूंगा, यह वास्तव में एक मुद्दा नहीं होना चाहिए।
मेरियो 21

1
एसपीए के लिए, मेरी ब्लॉग पोस्ट देखें: blog.wong2.me/2017/02/20/refresh-auth0-token-in-spa
wong2

2
मुझे लगता है कि (संभावित) सैकड़ों या हजारों अप्रयुक्त वैध JWTs होने के किसी भी समय वहाँ अपने हमले के पदचिह्न को बढ़ाता है और एक सुरक्षा जोखिम है। मेरे दिमाग में, JWTs को सावधानी से जारी किया जाना चाहिए क्योंकि वे एक तरीके से महल में चाबियों के साथ टोकन तक पहुंच रहे हैं।
जावा-व्यसनी ३०१

जवाबों:


589

मैं Auth0 पर काम करता हूं और मैं रिफ्रेश टोकन फीचर के डिजाइन में शामिल था।

यह सब आवेदन के प्रकार पर निर्भर करता है और यहां हमारा अनुशंसित दृष्टिकोण है।

वेब अनुप्रयोग

समाप्ति से पहले टोकन को रीफ्रेश करना एक अच्छा पैटर्न है।

टोकन समाप्ति को एक सप्ताह के लिए सेट करें और हर बार टोकन को रीफ़्रेश करें जब उपयोगकर्ता वेब एप्लिकेशन और हर एक घंटे को खोले। यदि कोई उपयोगकर्ता एक सप्ताह से अधिक समय तक आवेदन नहीं खोलता है, तो उन्हें फिर से लॉगिन करना होगा और यह स्वीकार्य वेब एप्लिकेशन है UX।

टोकन को रीफ्रेश करने के लिए आपके एपीआई को एक नया एंडपॉइंट की आवश्यकता होती है, जो कि एक वैध नहीं, एक्सपायर्ड जेडब्ल्यूटी को प्राप्त करता है और नए एक्सप्रेशन फील्ड के साथ उसी हस्ताक्षरित जेडब्ल्यूटी को लौटाता है। तब वेब एप्लिकेशन टोकन को कहीं स्टोर करेगा।

मोबाइल / नेटिव एप्लिकेशन

अधिकांश देशी एप्लिकेशन एक बार और केवल एक बार लॉगिन करते हैं।

विचार यह है कि ताज़ा टोकन कभी भी समाप्त नहीं होता है और इसे हमेशा एक वैध JWT के लिए एक्सचेंज किया जा सकता है।

एक टोकन के साथ समस्या जो कभी समाप्त नहीं होती है वह कभी नहीं होती है इसका मतलब नहीं है। यदि आप अपना फोन खो देते हैं तो आप क्या करते हैं? तो, इसे उपयोगकर्ता द्वारा किसी भी तरह पहचाने जाने की आवश्यकता है और एप्लिकेशन को पहुंच को रद्द करने का एक तरीका प्रदान करना होगा। हमने डिवाइस के नाम का उपयोग करने का निर्णय लिया, उदाहरण के लिए "मेरियो का आईपैड"। तब उपयोगकर्ता एप्लिकेशन पर जा सकता है और "मेरियो के आईपैड" तक पहुंच को रद्द कर सकता है।

एक और दृष्टिकोण विशिष्ट घटनाओं पर ताज़ा टोकन को रद्द करना है। एक दिलचस्प घटना पासवर्ड बदल रही है।

हम मानते हैं कि JWT इन उपयोग के मामलों के लिए उपयोगी नहीं है, इसलिए हम एक यादृच्छिक उत्पन्न स्ट्रिंग का उपयोग करते हैं और हम इसे अपने पक्ष में संग्रहीत करते हैं।


42
वेब अनुप्रयोगों के लिए दृष्टिकोण की सिफारिश की है, अगर टोकन एक सप्ताह के लिए वैध है तो क्या हम किसी को टोकन को रोकने और फिर इतने लंबे समय तक इसका उपयोग करने में सक्षम नहीं हैं? अस्वीकरण: मैं काफी नहीं जानता कि मैं किस बारे में बात कर रहा हूं।
user12121234

30
@wbgege हां इंटरसेप्शन एक मुद्दा है, यहां तक ​​कि कुकीज़ के साथ भी। आपको https का उपयोग करना चाहिए।
जोस एफ। रोमनिलो

15
@ JoséF.Romaniello आपके वेब उदाहरण में, टोकन स्टोर करने के अलावा मेरे लिए सब कुछ समझ में आता है। मुझे लगा कि जेडब्ल्यूटी की सुंदरता स्टेटलेस प्रमाणीकरण थी - जिसका अर्थ है कि वेब एप्लीकेशन को टोकन स्टोर करने की आवश्यकता नहीं है क्योंकि यह हस्ताक्षरित है। मुझे लगता है कि सर्वर सिर्फ टोकन की वैधता की जांच कर सकता है, सुनिश्चित करें कि यह समाप्ति की अवधि के भीतर है, और फिर एक नवीनीकृत JWT टोकन जारी करें। क्या आप इस बारे में विस्तार से बता सकते हैं? शायद मैं अभी तक JWTs को पर्याप्त नहीं समझता।
लो-टैन

7
दो प्रश्न / चिंताएँ: 1- वेब एप्लीकेशन का मामला: एक्सपायर टोकन को रिफ्रेश होने की अनुमति क्यों नहीं दी जा सकती? जैसा कि हमने कहा कि हम एक समय सीमा समाप्त होने पर बैकएंड सर्वर पर छोटी समाप्ति (1 घंटा) सेट करें और नए सिरे से कॉल करें। 2- क्या टोकन में हैशेड (यादृच्छिक नमक के साथ) पासवर्ड रखने के साथ सुरक्षा चिंता है? यह विचार है कि यदि यह वहां है, तो बैकेंड सर्वर नवीनीकरण के लिए पूछे जाने पर डीबी में संग्रहीत पासवर्ड के खिलाफ जांच कर सकता है और यदि पासवर्ड मेल नहीं खाते हैं तो अनुरोध को अस्वीकार कर सकते हैं। यह मोबाइल / नेटिव ऐप पासवर्ड परिवर्तन को कवर करेगा, जिससे समाधान को मोबाइल उपयोग के मामले में बढ़ाया जा सकेगा।
भजन

7
-1 एक सार्वजनिक एपीआई को उजागर करना जो अपनी मान्यता अवधि बढ़ाने के लिए किसी भी टोकन को नेत्रहीन रूप से फिर से हस्ताक्षर करता है। अब आपके सभी टोकन एक प्रभावी अनंत समाप्ति है। एक टोकन पर हस्ताक्षर करने के कार्य में हस्ताक्षर करने के समय उस टोकन में किए गए प्रत्येक दावे के लिए उपयुक्त सामान्य जांच शामिल होनी चाहिए।
फिल

69

उस स्थिति में जहां आप स्वयं को हैंडल करते हैं (जैसे कि किसी प्रदाता जैसे Auth0 का उपयोग न करें), निम्नलिखित काम कर सकता है:

  1. 15W कहना, अपेक्षाकृत कम समाप्ति के साथ जेडब्ल्यूटी टोकन जारी करें।
  2. आवेदन किसी भी लेन-देन की आवश्यकता से पहले टोकन समाप्ति की तारीख टोकन की जांच करता है (टोकन में समाप्ति की तारीख शामिल है)। यदि टोकन समाप्त हो गया है, तो यह पहले एपीआई को टोकन को 'रिफ्रेश' करने के लिए कहता है (यह UX के लिए पारदर्शी रूप से किया जाता है)।
  3. एपीआई को टोकन रिफ्रेश रिक्वेस्ट मिलती है, लेकिन पहले यूजर डेटाबेस को यह देखने के लिए चेक करता है कि क्या उस यूजर प्रोफाइल (टोकन में यूजर आईडी हो सकता है) के खिलाफ 'reauth ’फ्लैग सेट किया गया है। यदि ध्वज मौजूद है, तो टोकन ताज़ा करने से इनकार कर दिया जाता है, अन्यथा एक नया टोकन जारी किया जाता है।
  4. दोहराएँ।

डेटाबेस बैकेंड में 'reauth' ध्वज तब सेट किया जाएगा, उदाहरण के लिए, उपयोगकर्ता ने अपना पासवर्ड रीसेट कर दिया है। जब उपयोगकर्ता अगली बार लॉग इन करता है तो ध्वज हटा दिया जाता है।

इसके अलावा, मान लें कि आपकी कोई नीति है जिसके तहत उपयोगकर्ता को प्रत्येक 72hrs में कम से कम एक बार लॉगिन करना होगा। उस स्थिति में, आपका API टोकन रीफ़्रेश लॉजिक उपयोगकर्ता डेटाबेस से उपयोगकर्ता की अंतिम लॉगिन तिथि भी जाँच करेगा और उस आधार पर टोकन ताज़ा करने से इनकार / अनुमति दे सकता है।


7
मुझे नहीं लगता कि यह सुरक्षित होगा। अगर मैं हमलावर था और आपके टोकन को चुराकर सर्वर को भेज देता था, तो सर्वर जाँच करेगा और देखेगा कि झंडा सही पर सेट है जो बढ़िया है क्योंकि यह रिफ्रेश ब्लॉक कर देगा। मुझे लगता है कि समस्या यह होगी कि यदि पीड़ित ने अपना पासवर्ड बदल दिया है तो झंडा झूठा हो जाएगा और अब हमलावर ताज़ा करने के लिए उस मूल टोकन का उपयोग कर सकता है।
user2924127

6
@ user2924127 कोई भी वस्तु समाधान सही नहीं है, और हमेशा ट्रेडऑफ रहेगा। यदि कोई हमलावर 'आपका टोकन चुराने' की स्थिति में है, तो आपको चिंता करने के लिए अधिक मुद्दे हो सकते हैं। अधिकतम टोकन जीवनकाल सेट करना उपरोक्त के लिए एक उपयोगी मोड़ होगा।
इयान

27
डेटाबेस में एक और फ़ील्ड होने के बजाय, reauth फ्लैग, आप टोकन में hash (bcrypt_password_hash) के लिए शामिल कर सकते हैं। फिर टोकन को ताज़ा करते समय, आप बस पुष्टि करते हैं कि क्या हैश (bcrypt_password_hash) टोकन से मूल्य के बराबर है। टोकन रीफ़्रेश करने से इंकार करने के लिए, बस पासवर्ड हैश को अपडेट करना होगा।
बेस

4
@bas, अनुकूलन और प्रदर्शन के बारे में सोचते हुए, मुझे लगता है कि पासवर्ड हैश सत्यापन निरर्थक होगा और अधिक सर्वर निहितार्थ होगा। टोकन का आकार बढ़ाएं ताकि हस्ताक्षर फर्म / सत्यापन में अधिक समय लगे। पासवर्ड के लिए सर्वर के लिए अतिरिक्त हैश गणना। अतिरिक्त क्षेत्र दृष्टिकोण के साथ आप बस एक साधारण बूलियन के साथ पुनर्गणना में मान्य होते हैं। अतिरिक्त फ़ील्ड के लिए Db अद्यतन कम लगातार होता है, लेकिन अधिक बार ताज़ा ताज़ा होता है। और आपको किसी भी मौजूदा सत्र (मोबाइल, वेब इत्यादि) के लिए व्यक्तिगत पुन: लॉगिन बल की वैकल्पिक सेवा मिलती है।
le0diaz

6
मुझे लगता है कि user2924127 द्वारा पहली टिप्पणी वास्तव में गलत है। जब पासवर्ड बदल दिया जाता है, तो खाते को फिर से प्रमाणीकरण की आवश्यकता के रूप में चिह्नित किया जाता है, इसलिए किसी भी मौजूदा समय सीमा समाप्त टोकन अमान्य होंगे।
राल्फ

15

बैकएंड में Restful apis के साथ अपने एप्लिकेशनों को HTML5 में ले जाने पर मैं चारों ओर से छेड़छाड़ कर रहा था। जो समाधान मैं लेकर आया, वह था:

  1. क्लाइंट को सफल लॉगिन पर 30 मिनट (या सामान्य सर्वर साइड सत्र समय) के सत्र समय के साथ एक टोकन जारी किया जाता है।
  2. एक क्लाइंट-साइड टाइमर को एक सेवा को कॉल करने के लिए बनाया गया है ताकि वह समय समाप्त होने से पहले टोकन को नवीनीकृत कर सके। नया टोकन भविष्य की कॉल में मौजूदा की जगह लेगा।

जैसा कि आप देख सकते हैं, यह लगातार ताज़ा अनुरोधों को कम करता है। यदि उपयोगकर्ता नए सिरे से टोकन कॉल शुरू होने से पहले ब्राउज़र / ऐप को बंद कर देता है, तो पिछला टोकन समय समाप्त हो जाएगा और उपयोगकर्ता को फिर से लॉगिन करना होगा।

उपयोगकर्ता की निष्क्रियता को पूरा करने के लिए एक अधिक जटिल रणनीति को लागू किया जा सकता है (उदाहरण के लिए एक खोला ब्राउज़र टैब उपेक्षित)। उस स्थिति में, नवीनीकृत टोकन कॉल में अपेक्षित समाप्ति समय शामिल होना चाहिए जो निर्धारित सत्र समय से अधिक नहीं होना चाहिए। एप्लिकेशन को तदनुसार अंतिम उपयोगकर्ता इंटरैक्शन का ट्रैक रखना होगा।

मुझे लंबी समय सीमा समाप्त करने का विचार पसंद नहीं है, इसलिए यह दृष्टिकोण कम अनुप्रयोगों के साथ अच्छी तरह से काम नहीं कर सकता है, जिसमें कम प्रमाणीकरण की आवश्यकता होती है।


1
क्या होगा अगर कंप्यूटर निलंबित / सो गया था। टाइमर अभी भी समाप्ति तक गिना जाएगा लेकिन टोकन वास्तव में पहले ही समाप्त हो चुका था। टाइमर इस स्थिति में काम नहीं करता है
एलेक्स पारिज

@AlexParij आप एक निश्चित समय के खिलाफ तुलना करेंगे, कुछ इस तरह: stackoverflow.com/a/35182296/1038456
अपराजिता

2
पसंदीदा समाप्ति तिथि के साथ नए टोकन का अनुरोध करने के लिए ग्राहक को अनुमति देने से मेरे लिए सुरक्षा जोखिम की तरह गंध आती है।
जावा-आदी ३०१

14

JWTs को अमान्य करने के लिए एक वैकल्पिक समाधान, बैकएंड पर किसी भी अतिरिक्त सुरक्षित भंडारण के बिना, jwt_versionउपयोगकर्ता तालिका पर एक नया पूर्णांक स्तंभ लागू करना है । यदि उपयोगकर्ता मौजूदा टोकन को लॉग आउट या समाप्त करना चाहता है, तो वे बस jwt_versionक्षेत्र में वृद्धि करते हैं।

एक नया JWT जेनरेट jwt_versionकरते समय, JWT पेलोड में एनकोड करें , वैकल्पिक रूप से पहले से वैल्यू बढ़ाकर अगर नया JWT बाकी सभी को बदलना चाहिए।

जब जेडब्ल्यूटी को मान्य किया जाता है, तो jwt_versionक्षेत्र की तुलना में user_idऔर प्राधिकरण के साथ तुलना की जाती है , अगर यह मेल खाता है।


1
इससे कई उपकरणों के साथ समस्या है। अनिवार्य रूप से यदि आप एक डिवाइस पर लॉग आउट करते हैं, तो यह हर जगह लॉग आउट होता है। सही?
सैम वाशबर्न

4
अरे, यह आपकी आवश्यकताओं के आधार पर एक "समस्या" नहीं हो सकती है, लेकिन आप सही हैं; यह प्रति-डिवाइस सत्र प्रबंधन का समर्थन नहीं करता है।
ओली बेनेट

क्या इसका मतलब यह नहीं है कि jwt_version को सर्वर साइड में स्टोर किया जाना चाहिए जैसे कि प्रमाणीकरण योजना "सत्र-समान" हो जाती है और JWTs के मूल उद्देश्य को हरा देती है?
ChetPrickles

8

अच्छा सवाल- और सवाल में ही जानकारी का खजाना है।

लेख रीफ्रेश टोकन: जब उनका उपयोग करने के लिए और वे कैसे JWTs के साथ बातचीत इस परिदृश्य के लिए एक अच्छा विचार देता है। कुछ बिंदु हैं: -

  • ताज़ा टोकन एक नई पहुँच टोकन प्राप्त करने के लिए आवश्यक जानकारी ले जाता है।
  • ताज़ा टोकन भी समाप्त हो सकते हैं लेकिन लंबे समय तक जीवित रहते हैं।
  • ताज़ा टोकन आमतौर पर सख्त भंडारण आवश्यकताओं के अधीन होते हैं ताकि यह सुनिश्चित हो सके कि वे लीक नहीं हुए हैं।
  • उन्हें प्राधिकरण सर्वर द्वारा ब्लैकलिस्ट भी किया जा सकता है।

इस पर भी नजर डालें Cort0 / कोणीय-jwt कोणीयज

वेब एपीआई के लिए। ASP.NET .NET वेब एपीआई 2 और ओवेन का उपयोग करके AngularJS App में OAuth Refresh टोकन सक्षम करें पढ़ें


हो सकता है कि मैंने इसे गलत पढ़ा हो ... लेकिन एक शीर्षक के साथ लेख जो "रिफ्रेश टोकन ..." के रूप में शुरू होता है, इसमें ताज़ा टोकन के बारे में कुछ भी नहीं है, सिवाय इसके कि यहां उल्लेख क्या है।
इवगेन मार्टीनोव

8

मैंने वास्तव में एपीआई के लिए एक क्लाइंट लाइब्रेरी बनाने के लिए गूज़ल क्लाइंट का उपयोग करके पीएचपी में इसे लागू किया था, लेकिन अवधारणा को अन्य प्लेटफार्मों के लिए काम करना चाहिए।

असल में, मैं दो टोकन जारी करता हूं, एक छोटा (5 मिनट) एक और एक लंबा जो एक सप्ताह के बाद समाप्त हो जाता है। क्लाइंट लाइब्रेरी शॉर्ट टोकन के एक रिफ्रेश का प्रयास करने के लिए मिडलवेयर का उपयोग करती है अगर उसे कुछ अनुरोध के लिए 401 की प्रतिक्रिया मिलती है। यह फिर से मूल अनुरोध का प्रयास करेगा और यदि यह ताज़ा करने में सक्षम था, तो उपयोगकर्ता को पारदर्शी रूप से सही प्रतिक्रिया मिलती है। यदि यह विफल रहा, तो यह उपयोगकर्ता को 401 तक ही भेजेगा।

यदि छोटा टोकन समाप्त हो गया है, लेकिन फिर भी प्रामाणिक और लंबा टोकन वैध और प्रामाणिक है, तो यह सेवा पर एक विशेष समापन बिंदु का उपयोग करके लघु टोकन को ताज़ा करेगा कि लंबे टोकन प्रामाणिकता (यह एकमात्र ऐसी चीज है जिसके लिए इसका उपयोग किया जा सकता है)। इसके बाद नए लॉन्ग टोकन प्राप्त करने के लिए शॉर्ट टोकन का उपयोग किया जाएगा, जिससे हर बार एक और सप्ताह में इसे बढ़ाकर शॉर्ट टोकन को रिफ्रेश किया जा सकेगा।

यह दृष्टिकोण हमें अधिकतम 5 मिनट के भीतर पहुंच को रद्द करने की अनुमति देता है, जो टोकन के एक ब्लैकलिस्ट को स्टोर किए बिना हमारे उपयोग के लिए स्वीकार्य है।

देर से संपादित करें: मेरे सिर में ताज़ा होने के बाद इस महीने फिर से पढ़ना, मुझे यह इंगित करना चाहिए कि आप शॉर्ट टोकन को ताज़ा करते समय पहुंच को रद्द कर सकते हैं क्योंकि यह अधिक महंगी कॉल के लिए एक अवसर देता है (जैसे कि उपयोगकर्ता को देखने के लिए डेटाबेस पर कॉल करें आपकी सेवा में हर एक कॉल पर इसके लिए भुगतान किए बिना) पर प्रतिबंध लगा दिया गया है।


8

नीचे आपके JWT पहुँच टोकन को रद्द करने के चरण दिए गए हैं:

1) जब आप लॉगिन करते हैं, तो क्लाइंट के जवाब में 2 टोकन (एक्सेस टोकन, रिफ्रेश टोकन) भेजें।
2) एक्सेस टोकन का एक्सपायरी टाइम कम होगा और रिफ्रेश का लंबा एक्सपायरी टाइम होगा।
3) ग्राहक (फ्रंट एंड) अपने स्थानीय भंडारण में ताज़ा टोकन स्टोर करेगा और कुकीज़ में टोकन एक्सेस करेगा।
4) ग्राहक कॉलिंग एप के लिए एक्सेस टोकन का उपयोग करेगा। लेकिन जब यह समाप्त हो जाता है, तो स्थानीय भंडारण से ताज़ा टोकन चुनें और नया टोकन प्राप्त करने के लिए ऑवर सर्वर एप को कॉल करें।
5) आपके ऑर्ट सर्वर में एक एपीआई होगा जो ताज़ा टोकन स्वीकार करेगा और इसकी वैधता की जाँच करेगा और एक नया एक्सेस टोकन लौटाएगा।
6) एक बार ताज़ा टोकन समाप्त हो जाने पर, उपयोगकर्ता लॉग आउट हो जाएगा।

कृपया मुझे बताएं कि यदि आपको अधिक जानकारी की आवश्यकता है, तो मैं कोड (जावा + स्प्रिंग बूट) भी साझा कर सकता हूं।


यदि आपके पास GitHub में है तो क्या आप अपना प्रोजेक्ट लिंक साझा कर सकते हैं?
अरुण कुमार एन


6

जेडब्ल्यूटी-autorefresh

यदि आप नोड (प्रतिक्रिया / रिडक्स / यूनिवर्सल जेएस) का उपयोग कर रहे हैं तो आप स्थापित कर सकते हैं npm i -S jwt-autorefresh

यह लाइब्रेरी शेड्यूल टोकन एक्सपायरिंग (टोकन में एन्कोड किए गए एक्सप्रैस के आधार पर) से कुछ सेकंड पहले की गणना की गई उपयोगकर्ता की गणना में JWT टोकन का रिफ्रेश करती है। इसमें एक व्यापक परीक्षण सूट है और किसी भी अजीब गतिविधि को सुनिश्चित करने के लिए काफी कुछ शर्तों के लिए जांच की जाती है, जो आपके पर्यावरण से गलतफहमियों के बारे में एक वर्णनात्मक संदेश के साथ है।

पूर्ण उदाहरण कार्यान्वयन

import autorefresh from 'jwt-autorefresh'

/** Events in your app that are triggered when your user becomes authorized or deauthorized. */
import { onAuthorize, onDeauthorize } from './events'

/** Your refresh token mechanism, returning a promise that resolves to the new access tokenFunction (library does not care about your method of persisting tokens) */
const refresh = () => {
  const init =  { method: 'POST'
                , headers: { 'Content-Type': `application/x-www-form-urlencoded` }
                , body: `refresh_token=${localStorage.refresh_token}&grant_type=refresh_token`
                }
  return fetch('/oauth/token', init)
    .then(res => res.json())
    .then(({ token_type, access_token, expires_in, refresh_token }) => {
      localStorage.access_token = access_token
      localStorage.refresh_token = refresh_token
      return access_token
    })
}

/** You supply a leadSeconds number or function that generates a number of seconds that the refresh should occur prior to the access token expiring */
const leadSeconds = () => {
  /** Generate random additional seconds (up to 30 in this case) to append to the lead time to ensure multiple clients dont schedule simultaneous refresh */
  const jitter = Math.floor(Math.random() * 30)

  /** Schedule autorefresh to occur 60 to 90 seconds prior to token expiration */
  return 60 + jitter
}

let start = autorefresh({ refresh, leadSeconds })
let cancel = () => {}
onAuthorize(access_token => {
  cancel()
  cancel = start(access_token)
})

onDeauthorize(() => cancel())

अस्वीकरण: मैं अनुचर हूँ


इस बारे में प्रश्न, मैंने डिकोड फ़ंक्शन का उपयोग किया। क्या यह मान लिया जाए कि JWT को बिना किसी गुप्त प्रयोग के डिकोड किया जा सकता है? क्या यह JWT के साथ काम करता है जो एक रहस्य के साथ हस्ताक्षर किए गए थे?
जियान फ्रेंको ज़बारिनो सेप

3
हां, डीकोड एक क्लाइंट-ओनली डीकोड है और इसे रहस्य के बारे में पता नहीं होना चाहिए। JWT टोकन सर्वर-साइड पर हस्ताक्षर करने के लिए गुप्त का उपयोग यह सत्यापित करने के लिए किया जाता है कि मूल रूप से JWT उत्पन्न करने के लिए आपके हस्ताक्षर का उपयोग किया गया था और ग्राहक से कभी भी इसका उपयोग नहीं किया जाना चाहिए। JWT का जादू यह है कि इसके पेलोड को क्लाइंट-साइड डिकोड किया जा सकता है और अंदर के दावों का उपयोग बिना गुप्त के आपके UI को बनाने के लिए किया जा सकता है। केवल एक चीज jwt-autorefreshइसे डिकोड करती है, यह expदावा निकालने के लिए है ताकि यह निर्धारित किया जा सके कि अगला ताज़ा करने के लिए कितनी दूर है।
cchamberlain

1
ओह अच्छा पता है, कुछ मतलब नहीं था, लेकिन अब यह करता है। जवाब के लिए धन्यवाद।
जियान फ्रेंको ज़बारिनो सेप

4

मैंने टोकन डेटा में एक चर जोड़कर इस समस्या को हल किया:

softexp - I set this to 5 mins (300 seconds)

expiresInउपयोगकर्ता को फिर से लॉगिन करने के लिए मजबूर करने से पहले मैंने अपने इच्छित समय पर विकल्प सेट किया। मेरा 30 मिनट के लिए सेट है। यह मान से अधिक होना चाहिए softexp

जब मेरा क्लाइंट साइड ऐप सर्वर एपीआई (जहां टोकन आवश्यक है, जैसे ग्राहक सूची पृष्ठ) के लिए अनुरोध भेजता है, तो सर्वर यह जांचता है कि क्या जमा किया गया टोकन अभी भी वैध है या नहीं इसकी मूल समाप्ति ( expiresIn) मूल्य के आधार पर । यदि यह मान्य नहीं है, तो सर्वर इस त्रुटि के लिए विशेष रूप से एक स्थिति के साथ प्रतिक्रिया देगा। INVALID_TOKEN

यदि टोकन अभी भी expiredInमूल्य के आधार पर मान्य है , लेकिन यह पहले से ही पार कर गया हैsoftexp मूल्य , तो सर्वर इस त्रुटि के लिए एक अलग स्थिति के साथ जवाब देगा, जैसे। EXPIRED_TOKEN:

(Math.floor(Date.now() / 1000) > decoded.softexp)

ग्राहक पक्ष पर, अगर यह प्राप्त हुआ EXPIRED_TOKEN प्रतिक्रिया सर्वर पर एक नवीनीकरण अनुरोध भेजकर टोकन को स्वचालित रूप से नवीनीकृत करना चाहिए। यह उपयोगकर्ता के लिए पारदर्शी है और स्वचालित रूप से क्लाइंट ऐप का ध्यान रखा जा रहा है।

यदि टोकन अभी भी मान्य है, तो सर्वर में नवीनीकरण विधि को जांचना होगा:

jwt.verify(token, secret, (err, decoded) => {})

यदि उपरोक्त विधि विफल रही तो सर्वर टोकन नवीनीकृत करने से इंकार कर देगा।


यह रणनीति अच्छी लग रही है। लेकिन मुझे लगता है कि इसे "अधिकतम मात्रा में नवीनीकरण" के साथ पूरक होना चाहिए क्योंकि (शायद) एक उपयोगकर्ता सेसियोन हमेशा के लिए जीवित रह सकता है।
जुआन इग्नासियो बारिसिच

1
आप टोकन डेटा को हार्डकॉपी चर सेट कर सकते हैं ताकि टोकन को समाप्त करने के लिए अधिकतम तिथि निर्धारित की जा सके, या हो सकता है कि जब भी टोकन नवीनीकृत किया जाता है, तो कुल काउंटर नवीकरण की मात्रा को सीमित करते हुए एक काउंटर बनाया जाए।
जेम्स ए

1
यह सही है। मैं इसे "अवश्य" मानता हूं।
जुआन इग्नासियो बारिसिच

2

इस दृष्टिकोण के बारे में कैसे:

  • प्रत्येक क्लाइंट अनुरोध के लिए, सर्वर टोकन की समाप्ति तिथि (currentTime - lastAccessTime) के साथ तुलना करता है
  • यदि समाप्ति समय सीमा <(currentTime - lastAccessedTime) , तो यह अंतिम lastAccessedTime को वर्तमान समय में बदल देती है।
  • एक समय अवधि के लिए ब्राउज़र पर निष्क्रियता समाप्त होने की स्थिति में या समाप्ति के समय ब्राउज़र विंडो बंद हो गई थी और एक्सपायर टाइमटाइम> (currentTime - lastAccessedTime) , और फिर सर्वर टोकन को समाप्त कर सकता है और उपयोगकर्ता को फिर से लॉगिन करने के लिए कह सकता है।

हमें इस मामले में टोकन को ताज़ा करने के लिए अतिरिक्त समाप्ति बिंदु की आवश्यकता नहीं है। किसी भी फीडबैक की सराहना करेंगे।


क्या इस दिन यह एक अच्छा विकल्प है, यह कार्यान्वयन के लिए बहुत आसान है।
बी.बैन

4
इस मामले में, आप अंतिम बार कहां संग्रहीत करते हैं? आपको इसे बैकएंड और प्रति अनुरोध पर करना होगा, इसलिए यह एक वांछित समाधान नहीं है।
एंटीगर

2

आज, बहुत से लोग JWTs के साथ सत्र प्रबंधन करने के लिए चुनते हैं, जो कि कथित सादगी के लिए वे क्या दे रहे हैं, इसके बारे में पता किए बिना । मेरा उत्तर प्रश्नों के 2 भाग पर विस्तृत है:

फिर असली फायदा क्या है? केवल एक टोकन क्यों नहीं है (JWT नहीं) और सर्वर पर समाप्ति को बनाए रखें?

क्या अन्य विकल्प हैं? क्या JWT का उपयोग इस परिदृश्य के लिए अनुकूल नहीं है?

JWT कुछ सीमाओं के साथ बुनियादी सत्र प्रबंधन का समर्थन करने में सक्षम हैं। स्वयं-वर्णन टोकन होने के नाते, उन्हें सर्वर-साइड पर किसी भी राज्य की आवश्यकता नहीं है। यह उन्हें आकर्षक बनाता है। उदाहरण के लिए, यदि सेवा में दृढ़ता की परत नहीं है, तो इसे सत्र प्रबंधन के लिए एक लाने की आवश्यकता नहीं है।

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

अर्थात्, आप उन्हें मांग को अमान्य नहीं कर सकते। इसका मतलब है कि आप एक सुरक्षित लॉगआउट को लागू नहीं कर सकते हैं क्योंकि पहले से जारी टोकन को समाप्त करने का कोई तरीका नहीं है। आप निष्क्रिय समय-सीमा भी लागू नहीं कर सकते इसी कारण से । एक समाधान एक ब्लैकलिस्ट रखना है, लेकिन यह राज्य का परिचय देता है।

मैंने इन कमियों के बारे में विस्तार से बताते हुए एक पोस्ट लिखी । स्पष्ट होने के लिए, आप अधिक जटिलता (स्लाइडिंग सत्र, ताज़ा टोकन, आदि) जोड़कर इनके आसपास काम कर सकते हैं।

अन्य विकल्पों के लिए, यदि आपके क्लाइंट केवल एक ब्राउज़र के माध्यम से आपकी सेवा के साथ बातचीत करते हैं, तो मैं दृढ़ता से एक कुकी-आधारित सत्र प्रबंधन समाधान का उपयोग करने की सलाह देता हूं। मैंने वेब पर वर्तमान में व्यापक रूप से उपयोग की जाने वाली सूची प्रमाणीकरण विधियों का भी संकलन किया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.