【发布时间】:2013-02-19 10:13:33
【问题描述】:
我正在使用以下代码获取访问令牌,在连接到 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();
编辑:
这肯定是因为访问令牌已过期。这是意料之中的,但我想我每次打电话都会得到一个新的访问令牌。
但正如here所说:
如果 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;
}
像docs这样说
但是如何检查访问令牌是否过期或无效?
通过捕获异常 - 是唯一的解决方案吗?
实际上 Exception 是 java.io.FileNotFoundException 这没有意义。
【问题讨论】:
-
您是否有理由尝试手动执行此操作,而不是使用 PlusClient 上提供的方法?客户端应自动代表您的应用处理令牌交换。
-
我关注this 获取访问令牌。自动处理它的另一种方式是什么?
标签: android google-plus access-token