Использовать токен обновления, если токен аутентификации истек в учетной записи аутентификации

У меня есть приложение, которое использует AccountManager для хранения учетных записей пользователей. Пользователи регистрируются и регистрируются в моем REST-API с использованием учетных данных пароля пользователя OAuth2.0.

Точки доступа, которые пользователи получают, истекают через 2 часа и нуждаются в обновлении до истечения срока действия, и так далее.

Мне нужно реализовать эту обновляющую функциональность в моем аутентификаторе.

У меня есть модель под названием AccessToken которая имеет следующие поля:

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

Итак, в моем методе getAuthToken в классе AccessToken я получаю этот объект AccessToken и использую его поле AccessToken в качестве Auth Token для моего менеджера аккаунта.

Мне нужно как-то сохранить токен обновления и токен аутентификации с помощью моего диспетчера учетных записей и когда приложение попытается получить доступ к API и получит ответ об ошибке: {"error": "access token expired"} , чтобы обновить текущий токен доступа Используя строку refreshToken из объекта AccessToken полученного ранее. Тем не менее, я не уверен, как это сделать.

Мой метод getAuthToken в классе аутентификации выглядит следующим образом:

 @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 просто содержит некоторые константы:

 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 и будет взаимодействовать с API довольно часто, чтобы синхронизировать данные с и на сервере, и эти вызовы API также должны будут использовать токены доступа в качестве параметров в запросах, поэтому мне действительно нужно реализовать это обновление Функциональность и сделать ее автоматической.


Кто-нибудь знает, как правильно это реализовать?


PS: Я буду использовать локальную базу данных для хранения всех моих данных, и я также мог бы хранить объекты маркера. Это кажется легким взломом, хотя и небезопасным. Может быть, я всегда должен хранить только один токен обновления за раз в качестве записи db и обновлять его, когда приложение получает новый токен?

PPS: Я могу изменить способ работы API в любом случае, поэтому, если есть предложения по улучшению мобильного приложения, сделав API лучше, они также очень ценятся.

Вы можете сохранить токен обновления в пользовательских данных своей учетной записи при первом добавлении своей учетной записи, используя:

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

Вы также можете установить userdata после добавления учетной записи, вызвав:

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

Когда срок доступа к токену истек, вы можете получить токен обновления, вызвав:

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

Используйте refreshToken для получения нового токена доступа.

Intereting Posts
Фоновая запись видео в Android 4.0 Android inapp-billing – узнать версию API Заполнение JSON по этой ссылке на android Listview Я хочу упаковать значение перечисления в Bundle и получить как перечисление Mapbox не начинается с фрагмента Cardview не учитывает индекс z в относительной компоновке Gmail «Невозможно прикрепить пустой файл» Как скрыть название приложения в Android? Передача данных между внешним профилем приложения и внутренним профилем в Android Lollipop Android Shared menu между действиями Uiautomator – не может заставить ListView прокручиваться, когда я проверяю текст в каждом элементе списка. Он просто терпит неудачу, когда я нажимаю последний элемент на экране Время последнего доступа к файлам на Android Войти на сайт, используя учетную запись Android. Можно ли настроить компоновку заголовка предпочтений? Отключение интеллектуального текста для поля пароля на веб-сайтах