I am using the followin code to get an Access Token, after connecting to Google+, to get profile info and e-mail:
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");
This Access Token I am not storing and trying to re-use. Instead I ask for an Access Token everytime, expecting a new(different) Token, so that I don't need to check whether its expired etc..
But I am getting the same Access Token every time I ask for. I uninstalled the app, cleared data of Google+ App and still I get the same Access Token.
The Actual problem is, using this Access Token gives a 401 error - "message": "Invalid Credentials"
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
This is a response on browser.
On a device I get this in 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)
Line 269:
urlConnection = (HttpURLConnection) url.openConnection();
Complete Code:
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();
EDIT:
This is definitely because the Access Token is expired. Which was expected, but I thought I will get a new Access Token everytime I call.
But as said here:
If the android device already has an auth token (for the particular GData service you're trying to access), it will be returned to you
So, I have to do this:
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;
}
like the docs say
But how can I check if the Access Token is expired or invalid?
By catching the Exception - Is the only solution?
Actually the Exception is java.io.FileNotFoundException
which doesn't make sense.
Covering the bases here: Did you register a Google APIs Console project and create a OAuth 2.0 client ID for your Android app, by specifying your app's package name and the SHA-1 fingerprint of your certificate (test or prod)?
Often the 401 invalid credentials message is due to the APIs Console project either not being configured or one of the settings being invalid.
The steps to walk through that set up process specifically for the Google+ SDK are here: https://developers.google.com/+/mobile/android/getting-started
Edit
The PlusClient
can automatically handle your tokens for you. I'd suggest using the methods that the PlusClient
provides and allowing the client to manage the tokens rather than doing it manually. If you need email or profile data via the PlusClient
see PlusClient.loadPerson()
and for email PlusClient.getAccountName()
, more details at https://developers.google.com/+/mobile/android/people
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With