2015-12-30 11 views
9

में ऑथ टोकन की समयसीमा समाप्त होने पर रीफ्रेश टोकन का उपयोग करें मेरे पास एक ऐप है जो उपयोगकर्ताओं के खातों को संग्रहीत करने के लिए खाता प्रबंधक का उपयोग करता है। उपयोगकर्ता OAuth2.0 पासवर्ड-उपयोगकर्ता नाम प्रमाण-पत्र प्रवाह का उपयोग करके लॉग इन करते हैं और मेरे REST API के माध्यम से साइन अप करते हैं।खाता प्रमाणीकरण

उपयोगकर्ताओं को 2 घंटे में समाप्त होने वाली एक्सेस टोकन और फिर से समाप्त होने तक रीफ्रेश होने की आवश्यकता है, और इसी तरह।

मुझे अपने प्रमाणीकरणकर्ता में इस ताज़ा कार्यक्षमता को लागू करने की आवश्यकता है।

String accessToken, String tokenType, Long expiresIn, String refreshToken, String scope, Long createdAt:

मैं एक मॉडल AccessToken कहा जाता है जो निम्नलिखित क्षेत्रों है की है।

तो वर्तमान में, AccountAuthenticator कक्षा में मेरी getAuthToken विधि में मैं इस AccessToken वस्तु प्राप्त करते हैं और मेरी खाता प्रबंधक के लिए एक Auth Token के रूप में अपनी accessToken क्षेत्र का उपयोग करें।

मैं क्या जरूरत है किसी भी तरह स्टोर करने के लिए दोनों टोकन ताज़ा और प्रमाणन मेरे खाते प्रबंधक का उपयोग कर टोकन और तब होता है जब एप्लिकेशन API एक्सेस करने की कोशिश करता है और त्रुटि प्रतिक्रिया मिलती है: {"error": "access token expired"}, टोकन वर्तमान पहुँच ताज़ा करने के लिए से refreshToken स्ट्रिंग का उपयोग AccessToken ऑब्जेक्ट पहले प्राप्त हुआ था। हालांकि, मुझे यकीन नहीं है कि मुझे यह कैसे करना चाहिए।

प्रमाणक कक्षा में मेरे getAuthToken विधि वर्तमान में इस तरह दिखता है:

public class AccountGeneral { 

    public static final String ACCOUNT_TYPE = "com.discounty"; 

    public static final String ACCOUNT_NAME = "Discounty"; 

    public static final String AUTHTOKEN_TYPE_READ_ONLY = "Read only"; 

    public static final String AUTHTOKE_TYPE_READ_ONLY_LABEL = "Read only access to a Discounty account"; 

    public static final String AUTHTOKEN_TYPE_FULL_ACCESS = "Full access"; 

    public static final String AUTHTOKEN_TYPE_FULL_ACCESS_LABEL = "Full access to a Discounty account"; 
} 

एप्लिकेशन भी SyncAdapter का उपयोग किया जाएगा और यह करेगा:

@Override 
public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, 
          String authTokenType, Bundle options) throws NetworkErrorException { 
    if (!authTokenType.equals(AccountGeneral.AUTHTOKEN_TYPE_READ_ONLY) && 
      !authTokenType.equals(AccountGeneral.AUTHTOKEN_TYPE_FULL_ACCESS)) { 
     final Bundle result = new Bundle(); 
     result.putString(AccountManager.KEY_ERROR_MESSAGE, "Invalid authTokenType"); 
     return result; 
    } 

    final AccountManager manager = AccountManager.get(context.getApplicationContext()); 

    String authToken = manager.peekAuthToken(account, authTokenType); 

    Log.d("Discounty", TAG + " > peekAuthToken returned - " + authToken); 

    if (TextUtils.isEmpty(authToken)) { 
     final String password = manager.getPassword(account); 
     if (password != null) { 
      try { 
       authToken = discountyService.getAccessToken(DiscountyService.ACCESS_GRANT_TYPE, 
         account.name, password).toBlocking().first().getAccessToken(); 
// ======= 
// Here the above discountyService.getAccessToken(...) call returns 
// AccessToken object on which I call the .getAccessToken() 
// getter which returns a string. 
// ======= 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    if (!TextUtils.isEmpty(authToken)) { 
     final Bundle result = new Bundle(); 
     result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 
     result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 
     result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 
     return result; 
    } 

    final Intent intent = new Intent(context, LoginActivity.class); 
    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, accountAuthenticatorResponse); 
    intent.putExtra(LoginActivity.ARG_ACCOUNT_TYPE, account.type); 
    intent.putExtra(LoginActivity.ARG_AUTH_TYPE, authTokenType); 
    final Bundle bundle = new Bundle(); 
    bundle.putParcelable(AccountManager.KEY_INTENT, intent); 
    return bundle; 
} 

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


क्या कोई जानता है कि इसे सही ढंग से कैसे कार्यान्वित किया जाए?


पुनश्च: मैं अपने सभी डाटा स्टोर करने के लिए एक स्थानीय डेटाबेस का उपयोग किया जाएगा और मैं संग्रहीत कर सकती है टोकन के रूप में अच्छी तरह से वस्तुओं। यह एक आसान हैक की तरह लगता है, हालांकि असुरक्षित। हो सकता है कि मुझे हमेशा एक डीबी रिकॉर्ड के रूप में एक बार ताज़ा टोकन स्टोर करना चाहिए और इसे ऐप के रूप में अपडेट करना चाहिए क्योंकि ऐप को नया टोकन प्राप्त होता है?

पीपीएस: मैं एपीआई को किसी भी तरह से काम करने के तरीके को बदलने के लिए स्वतंत्र हूं, इसलिए यदि एपीआई को बेहतर बनाकर मोबाइल ऐप में सुधार करने के सुझाव हैं, तो उनकी भी सराहना की जाती है।फोन करके

Bundle userdata = new Bundle; 
userdata.putString("refreshToken", refreshToken); 
mAccountManager.addAccountExplicitly (account, password, userdata); 

तुम भी खाते को जोड़ने के बाद userdata सेट कर सकते हैं:

mAccountManager.setUserData(account, "refreshToken", refreshToken); 

+0

आपने रीफ्रेश टोकन प्राप्त करने का प्रबंधन कैसे किया? – thedarkpassenger

+0

@ डेनिस याकोवेन्को क्या आप अपने कोड साझा कर सकते हैं क्योंकि मैं यह समझने के लिए भी संघर्ष कर रहा हूं कि खाता प्रबंधक का उपयोग करके टोकन और सिंक कार्यक्षमता दोनों को कैसे प्रबंधित करें और रीफ्रेश करें। अगर आप – KJEjava48

+0

@ KJEjava48 कर सकते हैं तो साझा करें मैं यह नहीं कह सकता कि मुझे एक अच्छा समाधान मिला है यह और लिंक पर कोड अच्छा है, लेकिन फिर भी, [यहां पूरे ऐप के साथ मेरा रेपो है] (https://github.com/Discounty/Discounty.android)। 'ऐप/src/main/जावा/छूट/कॉम/गतिविधियों/LoginActivity.java' पर एक नज़र डालें। रीफ्रेश टोकन का उपयोग ज्यादातर वहां होता है। उम्मीद है कि यह आपके उदाहरण के लिए –

उत्तर

4

आप जब आप पहली बार उपयोग करके अपने खाते में जोड़ अपने खाते के उपयोगकर्ता डेटा में ताज़ा टोकन बचा सकता है जब आप टोकन तक पहुंच जाते हैं तो आप कॉल करके अपने रीफ्रेश टोकन को पुनर्प्राप्त कर सकते हैं:

String refreshToken = mAccountManager.getUserData(account, "refreshToken"); 

नया एक्सेस टोकन पुनर्प्राप्त करने के लिए रीफ्रेश टोकन का उपयोग करें।

+2

ध्यान दें कि आपको हमेशा 'setUserData'since' addAccountExplicitly' का उपयोग करके उपयोगकर्ता डेटा सेट करना चाहिए जिसे टूटा जाना जाता है। यह हमेशा बंडल में पारित उपयोगकर्ता डेटा सेट नहीं करता है। Http://stackoverflow.com/a/34601122/1558654 – Marten

+0

@ ग्रेस कोडर खाता प्रबंधक का उपयोग कर सर्वर से नया एक्सेस टोकन पुनर्प्राप्त करने के लिए रीफ्रेश टोकन का उपयोग कैसे करें। मैं खाता का उपयोग कर रीफ्रेश टोकन के साथ एक्सेस टोकन की समाप्ति का प्रबंधन कैसे कर सकता हूं प्रबंधक। कृपया उत्तर दें ... – KJEjava48

+0

@ KJEjava48 जब आप सर्वर से रीफ्रेश टोकन पुनर्प्राप्त करते हैं, तो सर्वर रीफ्रेश टोकन और रीफ्रेश टोकन की समाप्ति वापस कर देगा।फिर आपके खाता प्रबंधक में आपको यह जांचने की आवश्यकता है कि नए एक्सेस टोकन के लिए अनुरोध करने से पहले डिवाइस से वर्तमान दिनांक वापसी की तुलना करके रीफ्रेश टोकन की अवधि समाप्त हो गई है या नहीं। यदि रीफ्रेश टोकन की समयसीमा समाप्त हो गई है, तो आपको ओएथ 2 की पूरी प्रक्रिया को फिर से जाना होगा जिसमें उपयोगकर्ता को उसके पासवर्ड के लिए फिर से संकेत देना शामिल है। –

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