簡體   English   中英

Android OAuth2 Bearer令牌最佳做法

[英]Android OAuth2 Bearer token best practices

這個很好的教程非常好地介紹了Android上的帳戶身份驗證,並通過使用Android的AccountManager

但是,我需要使用承載令牌為OAuth2 API創建客戶端應用程序以進行身份​​驗證。 在獲得令牌時,我收到了它的到期時間戳,但我不清楚存儲的位置以及如何正確使用它。 問題是,如果我不想不必要地去服務器,應用程序會意識到,只有在請求任何隨機資源時從服務器收到HTTP 401錯誤后,承載才會變為無效。 那么,解決這個問題的最佳做法是什么:

  1. 我的代碼中的每個網絡請求都應該具有重試機制,以防承載令牌在此期間變為無效嗎? 在捕獲異常時我可能invalidateAuthToken並重試。
  2. 同步適配器能以某種方式幫助嗎?

由於我是Android開發的新手,我希望解決方案也可能與我預期的完全不同。

如果它是相關的,我打算使用Volley進行服務器通信。

經過一番調查后我發現了自己的答案:

  1. 是的,調用AccountManager#invalidateAuthToken將刪除上次保存的身份驗證令牌(OAuth2案例中的訪問令牌),並期望您在下一個AccountAuthenticator#getAuthToken調用中檢測到該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; } 

    我還收到了問題中提到的博客文章的作者的確認

  2. SyncAdapter無法直接幫助,因為它們的真正目的是異步(對於開發人員)和透明地(對於用戶)從網絡獲取數據。 他們只使用AbstractAccountAuthenticator並在適當的地方調用其方法。

之前我遇到了同樣的問題,並將此庫設置為Android中的handel OAuth2。 但該庫是Retrofit的擴展,它簡化了對OAuth 2提供程序進行身份驗證的過程,但您仍然可以使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM