android版Google plus:无效凭据

android版Google plus:无效凭据,android,google-plus,access-token,Android,Google Plus,Access Token,连接到Google+后,我使用以下代码获取访问令牌,以获取个人资料信息和电子邮件: String sAccessToken = GoogleAuthUtil.getToken(this,mPlusClient.getAccountName() + "", "oauth2:" + Scopes.PLUS_PROFILE + " https://www.googleapis.com/auth/u

连接到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+app的数据,但仍然得到了相同的访问令牌

实际问题是,使用此访问令牌会出现401错误-
“消息”:“无效凭据”

这是对浏览器的响应

在一台设备上,我在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();
完整代码:

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();
编辑:

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
,这毫无意义。

这里介绍了基本情况:您是否通过指定应用程序的包名和证书(测试或产品)的SHA-1指纹,为Android应用程序创建了OAuth 2.0客户端ID

401 invalid credentials消息通常是由于API控制台项目未配置或其中一个设置无效所致

下面是专门针对Google+SDK的设置过程的步骤:

编辑


PlusClient
可以自动为您处理代币。我建议使用
PlusClient
提供的方法,允许客户端管理令牌,而不是手动操作。如果您需要通过
PlusClient
查看
PlusClient.loadPerson()
和电子邮件
PlusClient.getAccountName()
获取电子邮件或个人资料数据,请参阅
PlusClient.getAccountName()

,我遇到了类似的问题。为了解决访问令牌过期的问题,我在客户端解码令牌,并检查令牌负载中的“exp”字段。这样,我可以在发送到服务器之前识别令牌过期。
更多细节在这里

是的,我做了你在回答中提到的一切。经过一番研究,我发现这肯定是因为
访问令牌
。是否有办法检查访问令牌是否过期或有效?有关如何验证/验证令牌的一些代码,请参阅quickstart示例,以便它们不仅有效,而且对给定的用户和应用程序也有效。Java服务器端应用程序验证可以在第140行看到:嘿@BrettJ,这对我来说过去是有效的,但就在几天前它停止了工作,现在它抛出了这个错误com.google.android.gms.auth.GoogleAuthException:未知。知道为什么吗?我的示波器有问题吗?您最近是否升级了SDK和Google Play服务?是否有理由尝试手动升级,而不是在PlusClient上使用提供的方法?客户端应该代表你的应用程序自动处理令牌交换。我随后获得了访问令牌。自动处理的另一种方式是什么?