nek*_*jsi 9 android accountmanager oauth-2.0 android-syncadapter android-volley
这个很好的教程非常好地介绍了Android上的帐户身份验证,并通过使用Android来实现AccountManager.
但是,我需要使用承载令牌为OAuth2 API创建客户端应用程序以进行身份验证.在获得令牌时,我收到了它的到期时间戳,但我不清楚存储的位置以及如何正确使用它.问题是,如果我不想不必要地去服务器,应用程序会意识到,只有在请求任何随机资源时从服务器收到HTTP 401错误后,承载才会变为无效.那么,解决这个问题的最佳做法是什么:
invalidateAuthToken在捕获异常时重试.由于我是Android开发的新手,我希望解决方案也可能与我预期的完全不同.
如果它是相关的,我打算使用Volley进行服务器通信.
经过一番调查后我发现了自己的答案:
是的,调用AccountManager#invalidateAuthToken将删除上次保存的身份验证令牌(OAuth2案例中的访问令牌),并期望您在下次AccountAuthenticator#getAuthToken调用时检测到该令牌.例如,以下是该方法的代码:
@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;
}
Run Code Online (Sandbox Code Playgroud)
我还收到了问题中提到的博客文章的作者的确认.
SyncAdapters无法直接帮助,因为它们的真正目的是异步(对于开发人员)和透明地(对于用户)从网络获取数据.他们只是AbstractAccountAuthenticator在适当的时候使用并调用它的方法.
| 归档时间: |
|
| 查看次数: |
6100 次 |
| 最近记录: |