Android OAuth2不记名标记最佳做法

这个很好的教程是一个非常好的介绍,Android上的帐户validation,并通过使用Android的AccountManager

不过,我需要使用承载令牌创buildOAuth2 API的客户端应用程序进行身份validation。 在获取令牌的时候,我会收到它的过期时间戳,但是我不清楚存储的位置以及如何正确使用它。 问题是,如果我不希望有不必要的旅行到服务器,应用程序会意识到,只有在请求任何随机资源时,服务器收到HTTP 401错误后,该载体才会失效。 那么,解决这个问题的最佳做法是什么?

  1. 我的代码中的每个networking请求是否应该有一个重试机制,以防持有者令牌在此期间失效? 捕捉exception并重试时,我可能invalidateAuthToken
  2. 可以同步适配器以某种方式帮助吗?

由于我是Android开发的新手,我预计解决scheme也可能会完全不同于我的预期。

如果相关,我打算使用Volley进行服务器通信。

Solutions Collecting From Web of "Android OAuth2不记名标记最佳做法"

经过一番调查,我发现了自己的答案:

  1. 是的,调用AccountManager#invalidateAuthToken会删除上次保存的身份validation令牌(OAuth2案例中的访问令牌),并希望您在下一个AccountAuthenticator#getAuthToken调用中检测到该身份validation令牌。 例如,以下是我为该方法的代码:

     @Override public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { // Extract the username and password from the Account Manager, and ask // for an appropriate AuthToken. final AccountManager am = AccountManager.get(mContext); String authToken = am.peekAuthToken(account, authTokenType); // EXTRA: I am also storing the OAuth2 refresh token in the AccountManager Map<String, String> refreshResult = null; String refreshToken = am.getUserData(account, KEY_REFRESH_TOKEN); if (TextUtils.isEmpty(authToken) && !TextUtils.isEmpty(refreshToken)) { // lets try to refresh the token // EXTRA: AuthenticationProvider is my class for accessing the authentication server, getting new access and refresh token based on the existing refresh token refreshResult = AuthenticationProvider. refreshAccessToken(am.getUserData(account, KEY_REFRESH_TOKEN)); } // If we get a result from the refresh - we return it if (!refreshResult.isEmpty()) { authToken = refreshResult.get(AccountManager.KEY_AUTHTOKEN); // EXTRA: new refresh token used only in OAuth2 refreshToken = refreshResult.get(KEY_REFRESH_TOKEN); final Bundle result = new Bundle(); result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); // store the new tokens in the system am.setAuthToken(account, authTokenType, authToken); am.setUserData(account, KEY_REFRESH_TOKEN, refreshToken); result.putString(AccountManager.KEY_AUTHTOKEN, refreshResult.get(AccountManager.KEY_AUTHTOKEN)); result.putString(KEY_REFRESH_TOKEN, refreshResult.get(KEY_REFRESH_TOKEN)); return result; } // If we get here, then we couldn't access the user's password - so we // need to re-prompt them for their credentials. We do that by creating // an intent to display our AuthenticatorActivity. final Intent intent = new Intent(mContext, LoginActivity.class); intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); final Bundle bundle = new Bundle(); bundle.putParcelable(AccountManager.KEY_INTENT, intent); return bundle; } 

    我也收到了问题中提到的博客作者的确认 。

  2. SyncAdapter不能直接帮助,因为它们的真正目的是从networkingasynchronous(对于开发人员)和透明地(对于用户)从networking获取数据。 他们只是使用AbstractAccountAuthenticator并在适当的地方调用它的方法。

我之前正在经历同样的问题,并使这个库在Android中处理OAuth2。 但该库是Retrofit的扩展,它简化了OAuth 2提供程序的身份validation过程,但仍然可以使用它。