2016-02-06 11 views
5

मैं रेट्रोफिट (2.0.0-बीटा 3) का उपयोग करने की कोशिश कर रहा हूं, लेकिन टोकन जोड़ने के लिए प्रमाणीकरणकर्ता का उपयोग करते समय, मुझे सिंक्रोनस कॉल से डेटा नहीं मिल रहा है। बैक-एंड पर हमारा लॉगिंग बहुत सारे लॉगिन प्रयास दिखाता है, लेकिन मुझे हेडर में वास्तव में जोड़ने के लिए शरीर से डेटा नहीं मिल सकता है।एंड्रॉइड - रेट्रोफिट 2 - प्रमाणीकरण परिणाम

public static class TokenAuthenticator implements Authenticator { 
    @Override 
    public Request authenticate(Route route, Response response) throws IOException { 
     // Refresh your access_token using a synchronous api request 
     UserService userService = createService(UserService.class); 

     Call<Session> call = userService.emailLogin(new Credentials("handle", "pass")); 

     // This call is made correctly, as it shows up on the back-end. 
     Session body = call.execute().body(); 

     // This line is never hit. 
     Logger.d("Session token: " + body.token); 

     // Add new header to rejected request and retry it 
     return response.request().newBuilder() 
       .header("Auth-Token", body.token) 
       .build(); 
     } 
    } 

मुझे बिल्कुल यकीन नहीं है कि यह कुछ भी प्रिंट क्यों नहीं कर रहा है। इस मुद्दे को हल करने के तरीके पर कोई सुझाव बहुत सराहना की जाएगी, मदद करने के लिए समय निकालने के लिए धन्यवाद।


ये स्रोत हैं जिन्हें मैं रेट्रोफिट को कार्यान्वित करने के तरीके पर पढ़ रहा हूं।

का उपयोग प्रमाणक:

+1

क्या आप वाकई gson एक तरह से यह आपके सत्र वर्ग को समझ सकता हूँ में कॉन्फ़िगर किया गया है कर रहे हैं? – gropapa

+1

ईमेल कॉलिंग (...) अतुल्यकालिक रूप से काम करता है, इसलिए मुझे नहीं लगता कि यह जीसन के साथ एक समस्या है। क्या यह बताने का कोई आसान तरीका है कि उस कॉल के साथ क्या गलत हो रहा है? मुझे कोई त्रुटि या कुछ भी नहीं दिखाई दे रहा है। –

उत्तर

5

मेरे पास समान प्रमाणीकरणकर्ता है और यह 2.0.0-बीटा 2 के साथ काम करता है।

यदि आपको प्रमाणीकरणकर्ता से बहुत से लॉगिन प्रयास मिलते हैं, तो मैं सुझाव देता हूं कि जब आप सिंक्रोनस कॉल करते हैं, तो आप उस कॉल के साथ प्रमाणीकरणकर्ता का उपयोग नहीं कर रहे हैं। यह लूप में समाप्त हो सकता है, अगर आपका "ईमेल लॉग इन" विफल रहता है।

इसके अलावा, मैं सर्वर से सभी यातायात को देखने के लिए जोड़ने loggingInterceptor की सिफारिश करेंगे: Logging with Retrofit 2

+1

आपके उत्तर के लिए धन्यवाद, और मैं इसे टोकन में वास्तव में जोड़ने के लिए प्राप्त कर लिया है; हालांकि, हर बार जब मैं एक और नेटवर्क कॉल कॉल करने का प्रयास करता हूं, तो यह वही काम करता है, इसलिए मुझे लगता है कि हेडर कॉल के बीच नहीं चलता है। आप प्रत्येक कॉल के लिए हेडर को कैसे सहेजते/सेट करते हैं? –

+1

मैं विशेष रूप से टोकन को डेटाबेस में संग्रहीत करता हूं और सभी कॉल के लिए "प्राधिकरण" शीर्षलेख में टोकन जोड़ता हूं। इसे कॉल करने के लिए इसे जोड़ें और टोकन को पैरामीटर के रूप में दें: @ हैडर ("प्रमाणीकरण") स्ट्रिंग bearer टोकन, –

+1

तो, मैं कॉल को बदल रहा हूं "कॉल getUser (@Header (" प्रमाणीकरण ") स्ट्रिंग टोकन); ", लेकिन फिर जब भी मैं इसे बुलाता हूं, मुझे टोकन में गुजरना होगा, जो समझ में आता है। लेकिन क्या ऐसा करने का एक साफ तरीका है? शायद एक इंटरसेप्टर या किसी भी तरह से कार्यों को लपेटने का उपयोग कर? –

8

मैं TokenAuthenticator और एक इंटरसेप्टर का उपयोग कर एक सभ्य समाधान पाने में कामयाब रहे और सोचा के रूप में यह कुछ अन्य लोगों की मदद कर सकते मैं विचार साझा करते हैं।

हेडर को टोकन जोड़ने वाले 'टोकनइंटरसेप्टर' वर्ग को जोड़ना टोकन मौजूद है, और टोकन प्रमाणीकरणकर्ता वर्ग कोई टोकन नहीं होने पर मामले को संभालता है, और हमें एक उत्पन्न करने की आवश्यकता होती है।

मुझे यकीन है कि इसे लागू करने के कुछ बेहतर तरीके हैं, लेकिन यह एक अच्छा प्रारंभिक बिंदु है जो मुझे लगता है।

public static class TokenAuthenticator implements Authenticator { 
    @Override 
    public Request authenticate(Route route, Response response) throws IOException { 
    ... 
    Session body = call.execute().body(); 
    Logger.d("Session token: " + body.token); 
    // Storing the token somewhere. 
    session.token = body.token; 
    ... 
} 


private static class TokenInterceptor implements Interceptor { 
@Override 
    public Response intercept(Chain chain) throws IOException { 
     Request originalRequest = chain.request(); 

     // Nothing to add to intercepted request if: 
     // a) Authorization value is empty because user is not logged in yet 
     // b) There is already a header with updated Authorization value 
     if (authorizationTokenIsEmpty() || alreadyHasAuthorizationHeader(originalRequest)) { 
      return chain.proceed(originalRequest); 
     } 

     // Add authorization header with updated authorization value to intercepted request 
     Request authorisedRequest = originalRequest.newBuilder() 
       .header("Auth-Token", session.token) 
       .build(); 
     return chain.proceed(authorisedRequest); 
    } 
} 

स्रोत:

http://lgvalle.xyz/2015/07/27/okhttp-authentication/

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