如何使用android客户经理处理刷新令牌

时间:2017-02-15 16:25:51

标签: android oauth-2.0 accountmanager

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

以下是获取令牌的示例方法:

@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();
}

1 个答案:

答案 0 :(得分:0)

我做了类似的事

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;

}