2015-09-02 12 views
5

मैं अपने एंड्रॉइड एप्लिकेशन में कई async अनुरोधों के साथ okhttp लाइब्रेरी का उपयोग कर रहा हूं। सभी अनुरोधों को हेडर में सेट करने के लिए टोकन की आवश्यकता होती है। कभी-कभी मुझे रिफ्रेश टोकन प्रदान करते हुए उस टोकन को रीफ्रेश करने की आवश्यकता होती है, इसलिए मैं OkHttp की प्रमाणीकरण कक्षा का उपयोग करने का निर्णय लेता हूं।Okhttp प्रमाणीकरण multithreading

क्या होगा जब 2 या अधिक एसिंक अनुरोधों को लगभग एक ही समय में सर्वर से 401 कोड मिलेगा?

@Override 
public Request authenticate(Proxy proxy, Response response) throws IOException 
{     
    return null; 
} 

प्रत्येक अनुरोध के लिए कहा जाता है प्रमाणक की विधि होगी, या यह सिर्फ पहला अनुरोध के लिए एक बार कहा जाएगा, कि 401 मिल गया?

टोकन को केवल एक बार रीफ्रेश कैसे करें?

उत्तर

1

मैं यहां दो परिदृश्य देखता हूं कि आप किस एपीआई को कॉल करते हैं।

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

अन्य परिदृश्य में थोड़ा और अधिक मुश्किल है - हर बार जब आप नए साख पुराने फोन सर्वर साइड से समाप्त हो गई हो की तैयारी में हैं। इसे संभालने के लिए आप एक नई वस्तु को एक सेमेस्टर के रूप में इस्तेमाल करने के लिए पेश करेंगे - यह हर बार अवरुद्ध होगा जब 'प्रमाण-पत्र रीफ्रेश किए जा रहे हैं'। यह सुनिश्चित करने के लिए कि आप केवल एक 'रीफ्रेश क्रेडेंशियल' कॉल करेंगे, आपको इसे कोड के ब्लॉक में कॉल करने की आवश्यकता है जो ध्वज के साथ सिंक्रनाइज़ किया गया है। यह यह की तरह लग सकता है:

synchronized(stateObject) { 
    if(!stateObject.isBeingRefreshed) return; 
    Response response = client.execute(request); 
    apiClient.setCredentials(response.getNewCredentials()); 
    stateObject.isBeingRefreshed = false; 
} 

आप ध्यान दिया है एक अतिरिक्त जांच if(!stateObject.isBeingRefreshed) return; निम्नलिखित अनुरोध जो 401 प्रतिक्रिया मिली द्वारा नए क्रेडेंशियल्स का अनुरोध रद्द करने के लिए है के रूप में।

+0

इस तरह, आप लौटे अनुरोधों को खो देते हैं, है ना? जिस तरह से मैंने नीचे रखा है, आप फिर से उन अनुरोधों को कॉल कर सकते हैं। – antonicg

+0

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

+0

यह सच है, यदि पुराने अनुरोधों को अवरुद्ध करने के लिए सर्वर पुरानी पहुंच की समयसीमा समाप्त नहीं करता है। घोषणा के लिए धन्यवाद। – antonicg

1

मेरे मामले में मैंने सिंगलटन पैटर्न का उपयोग करके Authenticator लागू किया। आप उस विधि को authenticate सिंक्रनाइज़ कर सकते हैं। उसके कार्यान्वयन में, मैं जाँच करता है, तो अनुरोध (Response वस्तु प्रमाणित विधि के पैरामीटर में प्राप्त से Request वस्तु हो रही) से टोकन एक ही है कि डिवाइस में सहेजे है (मैं एक SharedPreferences वस्तु में टोकन बचाने के लिए)।

टोकन में ही है, तो इसका मतलब है कि यह है कि यह अभी तक refresed नहीं किया गया है, तो मैं फिर से टोकन ताज़ा और वर्तमान अनुरोध को निष्पादित।

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

यदि आपको और मदद चाहिए, तो कृपया मुझे बताएं और मैं यहां कुछ कोड डालूंगा।

+1

मुझे लगता है कि यह जानकारी जोड़ना अच्छा होगा कि टोकन को सिंक्रोनस बनाने के लिए "लागू करें" विधि के बजाय "प्रतिबद्ध" विधि से सहेजा जाना आवश्यक है। –

+0

हां @ क्रिजिज़टोफक्रजनेकी, अच्छा बिंदु। मैं इसे ध्यान में भूल गया था। – antonicg

+0

हाय @ सैंटोनिक। क्या आप कुछ कोड प्रदान कर सकते हैं? मैं उन उदाहरणों को संभालने का एक तरीका ढूंढने की कोशिश कर रहा हूं जहां विभिन्न धागे एक ही समय में ताज़ा करने का प्रयास कर सकते हैं। ऐसा लगता है जैसे आपका जवाब मेरी समस्या का समाधान कर सकता है, लेकिन सिंक्रनाइज़ेशन वह जगह है जहां मैं फंस गया हूं और समझ में नहीं आता हूं। – JPM

संबंधित मुद्दे