Reputation: 2445
I have this method below that syncs data with my server. If I am logged in with a valid auth token, it works fine. But I am unsure how to make it work if the auth token is expired. In my iOS app, I check the "expires_in" value, and if it is expired, I use the refresh token to get a new auth token. But I am not sure how to do the same thing using the account manager. I am not sure where I handle getting the refresh token from the device and sending it to my server to get the new auth token.
Here is a sample method where I get the token:
@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
}
And here is my 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();
}
Upvotes: 3
Views: 2554
Reputation: 729
I did something like this
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;
}
Upvotes: 1