如何使用Android帐户管理器处理刷新令牌

如何使用Android帐户管理器处理刷新令牌

问题描述:

我有下面的这个方法与我的服务器同步数据。如果我使用有效的身份验证令牌登录,它可以正常工作。但是如果授权令牌过期,我不确定如何使它工作。在我的iOS应用程序中,我检查了“expires_in”值,如果它已过期,我使用刷新令牌来获取新的验证令牌。但我不确定如何使用客户经理做同样的事情。我不确定我在哪里处理从设备获取刷新令牌并将其发送到我的服务器以获取新的身份验证令牌。如何使用Android帐户管理器处理刷新令牌

下面是一个简单的方法,我得到令牌:

@Override 
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { 
    Intent i = new Intent("Sync Started"); 
    mContext.sendBroadcast(i); 

    String token = mAccountManager.blockingGetAuthToken(account, AccountGeneral.AUTHTOKEN_TYPE_FULL_ACCESS, true); 

    // do sync here using token 
} 

,这里是我的AbstractAccountAuthenticator - > getAuthToken:

@Override 
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { 
    Bundle result; 
    result = AuthHelper.getAccessTokenFromDevice(context, account, authTokenType); 
    if (result != null) { 
     return result; 
    } 
    final String refreshToken = AuthHelper.getRefreshTokenFromDevice(context, account); 
    if (refreshToken != null) { 
     result = AuthHelper.makeResultBundle(account, refreshToken, null); 
     return result; 
    } 
    if (AuthHelper.isAccountAvailable(context, account)) { 
     result = AuthHelper.makeResultBundle(account, null, null); 
     return result; 
    } 
    return new Bundle(); 
} 

我做了这样的事情

public Object getUserInfo(String token){ 

    try { 

     Log.d(TAG, "getUserInfo: "+token); 
     HttpHeaders headers = new HttpHeaders(); 
     headers.setContentType(MediaType.APPLICATION_JSON); 
     headers.add("token", token); 

     HttpEntity<String> request = new HttpEntity<>(null, headers); 

     RestTemplate restTemplate = new RestTemplate(); 
     restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); 

     ResponseEntity<User> obj = restTemplate.exchange(URL_API_GET_USER_INFO, HttpMethod.GET, request, User.class); 

     Log.d(TAG, "getUserInfo: returning User"); 
     return obj.getBody(); 
    } 
    catch (HttpClientErrorException e){ 

     if (e.getStatusCode().value() != 403){ 
      return e.getMessage(); 
     } 

     Log.d(TAG, "getUserInfo: forbidden, my current token is expired"); 

     //invalidate current token 
     AccountManager am = AccountManager.get(mContext); 
     am.invalidateAuthToken("cu.jaco.accountexample", token); 

     //request new token to my server 
     String mNewToken = requestToken(); 
     if (!StringUtils.isEmpty(mNewToken)){ 
      //if we get a new token call recursively getUserInfo with new token 
      return getUserInfo(mNewToken); 
     } 

     return e.getMessage(); 
    } 
    catch (RestClientException e){ 
     e.printStackTrace(); 
     Log.d(TAG, "getUserInfo: "+e.getMessage()); 
     return null; 
    } 
} 



private String requestToken(){ 

    if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.GET_ACCOUNTS) != PackageManager.PERMISSION_GRANTED) { 
     return null; 
    } 

    AccountManager mAccountManager = AccountManager.get(mContext); 
    Account[] acc = mAccountManager.getAccountsByType("cu.jaco.accountexample"); 

    //AccountAuthenticator is my class that extends form AbstractAccountAuthenticator 
    AccountAuthenticator authenticator = new AccountAuthenticator(mContext); 
    Bundle bundle; 
    try { 
     //ask directly for a new token 
     bundle = authenticator.getAuthToken(null, acc[0], "cu.jaco.accountexample.user", null); 
    } catch (NetworkErrorException e1) { 
     e1.printStackTrace(); 
     return e1.getMessage(); 
    } 

    String token = bundle.getString(AccountManager.KEY_AUTHTOKEN); 

    //refresh token in AccountManager 
    mAccountManager.setAuthToken(acc[0], "cu.jaco.accountexample.user", token); 

    return token; 

}