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

3
我有一个以下同步数据到服务器的方法。如果我使用有效的身份验证令牌登录,它可以正常工作。但是,如果身份验证令牌过期了,我不知道该如何使其继续工作。在我的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个回答

1
我做了类似这样的事情。
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;

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接