8

次のコードを使用してアクセス トークンを取得し、Google+ に接続した後、プロファイル情報と電子メールを取得しています。

String sAccessToken = GoogleAuthUtil.getToken(this,mPlusClient.getAccountName() + "",
                          "oauth2:" + Scopes.PLUS_PROFILE + " 
                          https://www.googleapis.com/auth/userinfo.profile 
                          https://www.googleapis.com/auth/userinfo.email");

このアクセス トークンは保存せず、再利用しようとはしていません。代わりに、新しい(異なる)トークンを期待して、毎回アクセストークンを要求するので、有効期限が切れているかどうかなどを確認する必要はありません..

しかし、要求するたびに同じアクセス トークンを取得しています。アプリをアンインストールし、 Google+ アプリのデータを消去しても、同じアクセス トークンを取得します。

実際の問題は、このアクセス トークンを使用すると 401 エラーが発生することです -"message": "Invalid Credentials"

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "authError",
    "message": "Invalid Credentials",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Invalid Credentials"
 }
}

これはブラウザの応答です。

デバイスでは、Logcat でこれを取得します。

02-25 02:09:46.919: W/System.err(3022): java.io.FileNotFoundException: https://www.googleapis.com/oauth2/v1/userinfo
02-25 02:09:46.929: W/System.err(3022):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:521)
02-25 02:09:46.929: W/System.err(3022):     at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:258)
02-25 02:09:46.929: W/System.err(3022):     at com.example.gmaillogin.MainActivity$connectAsyncTask.doInBackground(MainActivity.java:269)
02-25 02:09:46.929: W/System.err(3022):     at com.example.gmaillogin.MainActivity$connectAsyncTask.doInBackground(MainActivity.java:1)
02-25 02:09:46.929: W/System.err(3022):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
02-25 02:09:46.929: W/System.err(3022):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
02-25 02:09:46.929: W/System.err(3022):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
02-25 02:09:46.929: W/System.err(3022):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
02-25 02:09:46.929: W/System.err(3022):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
02-25 02:09:46.929: W/System.err(3022):     at java.lang.Thread.run(Thread.java:1019)

269 行目:

urlConnection = (HttpURLConnection) url.openConnection();

完全なコード:

URL url = new URL("https://www.googleapis.com/oauth2/v1/userinfo");
String sAccessToken = GoogleAuthUtil.getToken(
                        MainActivity.this,
                        mPlusClient.getAccountName() + "",
                        "oauth2:" + Scopes.PLUS_PROFILE + " 
                                            https://www.googleapis.com/auth/userinfo.profile 
                                            https://www.googleapis.com/auth/userinfo.email");

            Log.d("sAccessToken = ", "" + sAccessToken);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestProperty("Authorization", "Bearer "
                    + sAccessToken);

            BufferedReader r = new BufferedReader(new InputStreamReader(
                    urlConnection.getInputStream(), "UTF-8"));
            StringBuilder total = new StringBuilder();
            String line;
            while ((line = r.readLine()) != null) {
                total.append(line);
            }
            line = total.toString();

編集:

これは間違いなく、アクセス トークンの有効期限が切れているためです。これは予想通りでしたが、呼び出すたびに新しいアクセス トークンを取得できると思いました。

しかし、ここで言ったように:

Android デバイスに (アクセスしようとしている特定の GData サービス用の) 認証トークンが既にある場合は、それが返されます。

だから、私はこれをしなければなりません:

if (server indicates token is invalid) {
              // invalidate the token that we found is bad so that GoogleAuthUtil won't
              // return it next time (it may have cached it)
              GoogleAuthUtil.invalidateToken(Context, String)(context, token);
              // consider retrying getAndUseTokenBlocking() once more
              return;
          }

ドキュメントが言うように

しかし、アクセス トークンが期限切れか無効かを確認するにはどうすればよいですか?

例外をキャッチすることによって - 唯一の解決策ですか?

実際、例外はjava.io.FileNotFoundException意味をなさないものです。

4

2 に答える 2

4

ここでベースをカバーします: Google API コンソール プロジェクトを登録し、アプリのパッケージ名と証明書 (テストまたは製品) の SHA-1 フィンガープリントを指定して、Android アプリ用の OAuth 2.0 クライアント ID を作成しましたか?

多くの場合、401 無効な資格情報メッセージは、API コンソール プロジェクトが構成されていないか、設定の 1 つが無効であることが原因です。

Google+ SDK 専用のセットアップ プロセスを実行する手順は、https ://developers.google.com/+/mobile/android/getting-started にあります。

編集

PlusClientトークンを自動的に処理できます。PlusClientが提供するメソッドを使用し、手動で行うのではなく、クライアントがトークンを管理できるようにすることをお勧めします。PlusClientseePlusClient.loadPerson()および for emailを介してメールまたはプロファイル データが必要な場合は、 https://developers.google.com/+/mobile/android/peoplePlusClient.getAccountName()で詳細を確認してください。

于 2013-03-05T18:51:15.757 に答える
0

同様の問題がありました。アクセス トークンの有効期限の問題を解決するために、クライアント側でトークンをデコードし、トークン ペイロードの「exp」フィールドを確認します。そうすれば、サーバーに送信する前にトークンの有効期限を認識できます。詳細については、このブログ投稿を参照してください

于 2013-06-11T12:10:11.690 に答える