17

SyncAdapterデータベース同期を処理するために使用する新しい Android アプリを作成しています。すべてが整っており、アプリは正常に動作していますが、2 回ログインしていることに気付きました。

最初のログインは、AuthenticatorActivityクラス (拡張AccountAuthenticatorActivity) がユーザーとパスワードを検証するときに行われます。

ユーザーとパスワードが正しい場合は、次のようになりますAuthenticatorActivity

  • が存在しない場合は、accountそれを使用して作成しますmAccountManager.addAccountExplicitly()
  • を使用authTokenして保存されますintent.putExtra(AccountManager.KEY_AUTHTOKEN, authToken);

これは基本的に Android のサンプルからコピペしたものなので、問題ないと思います。

問題は、SyncAdapter起動して使用するときです

authtoken = mAccountManager.blockingGetAuthToken(account,
          AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, true);

拡張するクラス内のgetAuthToken()メソッドが呼び出されます。そして、このメソッド内で、もう一度ログイン エンドポイントにアクセスしています。AuthenticatorAbstractAccountAuthenticator

それ以降は、有効期限が切れるまで、ログイン エンドポイントに再度ヒットすることはありませんauthToken

これはあまり気になりませんが、ログインを 2 回行わないようにする方法があれば教えてください。

4

1 に答える 1

15

ご覧のとおり、 SampleSyncAdapterAuthenticator.javaでは

このクラスが示す興味深い点は、認証プロセスの一部としての authToken の使用です。... アカウントに既に authToken が保存されている場合は、その authToken を返します。持っていなくても、ユーザー名とパスワードがある場合は、サンプル サービスと通信して authToken を取得しようとします。

それはうそです。 Authenticator.getAuthTokenキャッシュチェックは行わず、ネットワークにアクセスしてトークンを取得するだけです。

解決策は、不足しているチェックを追加することです。

Authenticator.java:
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
        String authTokenType, Bundle loginOptions) throws NetworkErrorException {

    // check that authToken type supported
    ...

    // Check if we already have a cached token to return
    final AccountManager am = AccountManager.get(mContext);
    String cachedAuthToken = am.peekAuthToken(account, authTokenType);
    if (cachedAuthToken != null) {
        final Bundle result = new Bundle();
        result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
        result.putString(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
        result.putString(AccountManager.KEY_AUTHTOKEN, cachedAuthToken);
        return result;
    }

    // Get new authToken from server
    ...

    // If all else fails, prompt the user for credentials
    ...
}

プロジェクトの残りの部分は、AccountManager.invalidateAuthToken呼び出しが失敗したときに宗教的に使用する必要があることに注意してください。そうしないと、呼び出しが失敗し、新しい認証トークンを取得しようとし、同じキャッシュされた認証トークンが返されたときに再び失敗するという無限ループが発生します。

于 2012-07-30T20:24:07.720 に答える