私はかなり憤慨しています。 AndroidのサーバーとしてGoogleApp Engineを使用して、Javaのターンベースのマルチプレイヤーオンラインゲームを構築しようとしています。
彼らは完璧にフィットしているようです。 AndroidにはGoogleアカウントが必要です。GAEは認証にGoogleアカウントを使用しますが、無料でスケーラブルです。
そのため、休日の前に、Android 2.0の新しいAccountManagerAPIを使用して、AndroidクライアントからGAEアプリへの認証を取得できました。次のコードを使用すると、ユーザーのGoogleアカウントのAuthTokenにアクセスし、それを認証に使用して、ユーザーがアカウントのユーザー名とパスワードを手動で入力する必要がないようにします。
AccountManager mgr = AccountManager.get(this);
Account[] accts = mgr.getAccountsByType("com.google");
Account acct = accts[0];
AccountManagerFuture<Bundle> accountManagerFuture = mgr.getAuthToken(acct, "ah", null, this, null, null);
Bundle authTokenBundle = accountManagerFuture.getResult();
String authToken = authTokenBundle.get(AccountManager.KEY_AUTHTOKEN).toString();
次に、結果のAuthToken文字列を適切なURLに追加して、その後のすべての要求に使用できる有効なCookieを取得できました。唯一のことは、先週いつかそれが私のために機能しなくなったということです。上記のコードからAuthTokenを使用しようとすると、Cookieが返されず、不足しているCookieに対してコードがNullPointerExceptionをスローします。
以前の方法に戻ると、ユーザーがGoogleのユーザー名とパスワードを手動で入力していて、「 https://www.google.com/accounts/ClientLogin "」からAuthTokenを取得しました。それはうまくいきます。
誰かがユーザーの電話のGoogleアカウントからAuthTokenを使用してGoogleAppEngineアプリ用のAndroidクライアントを構築したことを教えてください。また、これがなくなった理由についていくつかの手がかりを教えてください。ワーキング。
私は本当にこの仕事をしたいと思います。私の代替策は、ユーザーに資格情報の入力を要求することです(これは不格好で、ユーザーが行う必要はありません)、またはサーバーの別のソリューションを使用することです。
前もって感謝します。
これについては、Googleのエンジニアから助けを得ました。 authTokenの有効期限が切れていることがわかりました。私は当初、12月初旬(正確には9日)に実装を機能させていました。どうやらAccountManagerが行うのはauthTokenをキャッシュすることなので、12月9日から同じauthTokenを使用していました。私が休日から戻ったとき、それは期限切れでした。
この問題を解決するために、getAuthTokenを呼び出してから、そのトークンでinvalidateAuthTokenを呼び出してから、もう一度getAuthTokenを呼び出します。これにより、有効なauthTokenが生成され、少し不格好で、AccountManagerが毎回新しいauthTokenを取得したり、キャッシュされたauthTokenの有効期限が切れているかどうかを確認したりする場合は不要ですが、問題なく機能します。
トークンタイプとアカウントタイプを混同しないように注意してください。invalidateAuthTokenは「ah」ではなく「com.google」で呼び出す必要があります。そうしないと、サイレントに失敗します。
それ自体は答えではありませんが、Android v2.2.1のAndroidネクサス1で正しいトークンを取得するには、4行目の「ah」を「Android」に置き換える必要がありました。他のデバイス/バージョンについてはよくわかりません。 4行目は次のようになります。
... = mgr.getAuthToken(acct, "ah", null, this, null, null);
に:
... = mgr.getAuthToken(acct, "Android", null, this, null, null);