AuthToken from AccountManager in Android Client No Longer Working

22,157

Solution 1

Got help for this from a Google engineer. Turns out my authToken was expired. I had initially gotten the implementation working in early December (the 9th to be exact). Apparently what the AccountManager does is cache the authToken, so I had been using the same authToken since Dec. 9th. When I got back from the holidays it had expired.

To solve the issue, I now call getAuthToken, then call invalidateAuthToken on that token, then call getAuthToken again. This generates a valid authToken and works just fine, even if it is a little clunky and would be unnecessary if AccountManager just got a fresh authToken each time, or did a check to see if the cached one was expired.

Note that you must not mix up token type with account type: invalidateAuthToken must be called with "com.google" instead of "ah" or it will silently fail.

Solution 2

not an answer per se, but i had to substitute the "ah" with "android" in line 4 to get the correct token on an android nexus one with android v2.2.1. not sure about other devices/versions. line 4 then turns from :

... = mgr.getAuthToken(acct, "ah", null, this, null, null);

into :

... = mgr.getAuthToken(acct, "android", null, this, null, null);
Share:
22,157
polyclef
Author by

polyclef

Updated on June 20, 2020

Comments

  • polyclef
    polyclef almost 4 years

    I'm pretty exasperated. I'm attempting to build a turn-based multiplayer online game for Android using Google App Engine in Java as the server.

    They seem like a perfect fit. Android requires a Google account, and GAE uses a Google account for authentication, while being free and scalable.

    So before the holidays I was able to get authentication to my GAE app from my Android client using the new AccountManager API in Android 2.0. The following code allows you to access the AuthToken of the user's Google account and then use it for authentication, so that the user does not have to manually enter their account username and password:

       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();
    

    I was then able to append the resulting AuthToken string to the appropriate URL and get a valid cookie which I could then use for all further requests. Only thing is, sometime last week it just stopped working for me. Now when I try to use the AuthToken from the above code, I don't get a cookie returned and my code throws a NullPointerException for the missing cookie.

    When I go back to the old way, when the user was manually entering in their Google username and password and I get the AuthToken from "https://www.google.com/accounts/ClientLogin", it works just fine.

    Please tell me someone out there has built an Android client for a Google App Engine app using the AuthToken from the Google account on the user's phone, and give me some clue as to why this is no longer working.

    I'd really like to make this work. My alternatives are to require the user to enter their credentials (which is clunky, and which they shouldn't have to do), or going with another solution for the server.

    Thanks in advance.

  • Billy Bob Bain
    Billy Bob Bain about 14 years
    I had the same issue & the invalidateAuthToken is the key. You'll need the android.permission.MANAGE_ACCOUNTS permission granted.
  • Artem
    Artem over 13 years
    Tip: When you call invalidateAuthToken, make sure you pass account type ("com.google") and not token type ("health"). I made this mistake and it took a while to track down because invalidateAuthToken returns no errors.
  • kellogs
    kellogs about 13 years
    No offense, but please see the manual developer.android.com/reference/android/accounts/…
  • Soham
    Soham over 12 years
    @Artem u are a life saver, tried putting the token type in the invalidate and it just DID NOT work, you saved my life :) Thanks a ton!
  • Admin
    Admin over 12 years
    Where exactly do you have the invalidateAuthToken call? The callback isn't used until the user is done trying (and failing) to enter a password.
  • KK_07k11A0585
    KK_07k11A0585 over 12 years
    Many Thanks for your answer! I am able to get the auth token of an account. But, i want the password of the account. Please tell me where i have to pass the authToken so that i can get the password of account. Please help me i was new to Accounts. All i want is username and password of all gmail accounts that are stored in android device such that i can send an email to them using Gmail Sender
  • atraudes
    atraudes over 12 years
    I had the same problem as this guy groups.google.com/group/android-developers/browse_thread/thr‌​ead/… and your response saved me. Thank thank thank you!
  • atraudes
    atraudes over 12 years
    There was also this response to his issue here for future generation's reference: groups.google.com/group/android-developers/browse_thread/thr‌​ead/…
  • Aaron Dufour
    Aaron Dufour almost 12 years
    @KK_07k11A0585 There is no way Android is ever going to give away anyone's Google passwords.