OAuth2ErrorException invalid_token when verifying

2019-07-04 11:59发布

问题:

First time using the Google+ API. I have an application with a web and Android client that uses G+ for authentication. Web client is working nicely. I have a "Client ID for web application" set up in the Google API console, which I use to fetch a token with a javascript client.

The javascript client uses the following button (taken basically verbatim from a Google demo app):

<button class="g-signin"
       data-scope="https://www.googleapis.com/auth/plus.login"
       data-requestvisibleactions="http://schemas.google.com/AddActivity"
       data-clientId="my_web_application_client_id"
       data-callback="onSignInCallback"
       data-theme="dark"
       data-cookiepolicy="single_host_origin">

I verify on the Python server with:

url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s' % token)
 h = httplib2.Http()
  result = json.loads(h.request(url, 'GET')[1])

So far so good. Token verifies as expected.

Now for the android app... I set up a "Client ID for android application" for the same project with a debug fingerprint generated by: keytool -exportcert -alias androiddebugkey -keystore debug.keystore -list -v

The package for the client id name matches what's in my Android manifest.

I'm using GoogleAuthUtil to generate a token in my Android app:

String token =
  GoogleAuthUtil.getToken(
    this,
    "selected@email.address",
    "oauth2:server:client_id:<client_id>:" +
      "api_scope:https://www.googleapis.com/auth/plus.login");

If I use my my newly-created android app client id, I get: GoogleAuthException: com.google.android.gms.auth.GoogleAuthException: Unknown

I haven't figured that one out yet, but some solutions hint that I should just be using the web application client id and that the Exception is working as intended.

If I use my web application client id, then everything appears to work just fine and a token is returned, but when I send the token to my server to verify, the token gets rejected:

{u'error_description': u'Invalid Value', u'debug_info': u'code: INVALID_VALUE
http status: 400
arguments: [invalid_token]
cause: com.google.security.lso.protocol.oauth2.common.OAuth2ErrorException:\
 invalid_token at
com.google.security.lso.grant.token.TokenManager.getTokenInfo(TokenManager.java:603) at
com.google.security.lso.apiary.tokeninfo.TokenInfoAction.execute(TokenInfoAction.java:92)

I've verified the token arriving at the server is the same one that is fetched in the app (no stray whitespace, etc).

Any ideas what I'm doing wrong? Thanks for any suggestions!

回答1:

What I ended up doing is the following:

When calling GoogleAuthUtil, instead of the following scope:

oauth2:server:client_id:<client_id>:api_scope:https://www.googleapis.com/auth/plus.login

I used:

audience:server:client_id:<client_id>

where client_id is the web client id.

This produces a much longer token. You can decrypt/authenticate this token via:

https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=<token>

Note that the query param key is id_token, not access_token.

The server responds with the following:

{
 "issuer": "accounts.google.com",
 "issued_to": "<android_client_id>",
 "audience": "<web_client_id>",
 "user_id": "<some_long_integer>",
 "expires_in": 3354,
 "issued_at": 1406474776,
 "email": "<email address passed to GaiaAuthUtil>",
 "verified_email": true
}

On your server, you then:

  1. Verify that the audience and issued_to strings are what you expect
  2. Verify the userid/email is authorized

then carry on with the request processing.

This solution is a mixture of information from other StackExchange discussions and this tutorial: http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html

Hope this will save someone some time!