2
votes

I just recently was able to refactor my app engine application to support Cloud Endpoints after watching the IMO helpful GDL episodes on YouTube.

I'm testing my site using the javascript client to handle authorization and then return a list of items which mostly works. But when I'm calling the endpoint to return the list of items I get this set of errors in my App Engine logs:

I 2013-03-14 08:52:14.748 Checking for id_token.
W 2013-03-14 08:52:14.748 id_token verification failed: Wrong number of segments in token: ya29.AHES6ZSpbeiTPTOJhCTtRdypgldcrRBQBKH8oQ8Y_FpxG5-Lr3OW6dE
I 2013-03-14 08:52:14.748 Checking for oauth token.
W 2013-03-14 08:52:14.885 Found 1 RPC request(s) without matching response (presumably due to timeouts or other errors)

From what I can tell there are only 2 "segments" in all the auth tokens that google is returning not 3 so I'm not clear what this means.

Here's the Authorization request header from my browser console: Authorization Bearer ya29.AHES6ZSpbeiTPTOJhCTtRdypgldcrRBQBKH8oQ8Y_FpxG5-Lr3OW6dE

Any help would be appreciated.

1

1 Answers

8
votes

There are two types of tokens: ID tokens and standard Bearer tokens.

Bearer Token:

This is the standard token retrieved through the OAuth dance.

ID Token:

A typical ID token will look something like eyJhbGciOiJSUzI1NiIsImtpZCI6IjIxZWFlMTVkODE.eyJpc3MiOiJhY2NvdW50cy5n.oXLawgz_ed (except with segments that are much longer) and is a signed JWT.

An ID token can be obtained in JavaScript by adding 'id_token' to the response type, as is done in our Tic-Tac-Toe sample.

This way, the token returned from the OAuth request will also have an ID token:

var token = gapi.auth.getToken();
// Use id_token instead of bearer token
token.access_token = token.id_token;    

What You Are Seeing in the Logs:

The line

W 2013-03-14 08:52:14.748 id_token verification failed: Wrong number of segments in token: ya29.AHES6ZSpbeiTPTOJhCTtRdypgldcrRBQBKH8oQ8Y_FpxG5-Lr3OW6dE

is only a warning, meaning that the observed token ya29.AHE... is not an ID token and the next line in the log

I 2013-03-14 08:52:14.748 Checking for oauth token.

means that it is moving on to check if the token is a Bearer Token.

This DOES NOT mean your token was invalid, just that it was checking the Bearer Token.

The line

W 2013-03-14 08:52:14.885 Found 1 RPC request(s) without matching response (presumably due to timeouts or other errors)

likely means there was an RPC to verify the token that failed. The main pieces to verify a Bearer Token are a call to

oauth.get_current_user(EMAIL_SCOPE)

and a request to

https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=ya29.AHE...

to verify the Client ID and Audience on the token.

ID Token In Depth:

The first segment is a base64url encoded description of the encryption used. For example.

>>> import base64, json
>>> segments = id_token.split('.')
>>> first_segment = segments[0] + '=' * ((4 - len(segments[0])) % 4)
>>> json.loads(base64.urlsafe_b64decode(first_segment))
{u'alg': u'RS256', u'kid': u'21eae15d817c1b4a8f6ff4501930512d07cbe684'}

the second segment is a base64url encoded decription of the token's contents:

>>> second_segment = segments[1] + '=' * ((4 - len(segments[0])) % 4)
>>> base64.urlsafe_b64decode(second_segment)
{u'at_hash': u'xxxyyyzzz',  # Fake Data
 u'aud': u'someclient_id.apps.googleusercontent.com',
 u'azp': u'someclient_id.apps.googleusercontent.com',
 u'cid': u'someclient_id.apps.googleusercontent.com',
 u'email': u'[email protected]',
 u'email_verified': u'true',
 u'exp': 1363289943,
 u'hd': u'google.com',
 u'iat': 1363286043,
 u'id': u'123456789',  # Fake Data
 u'iss': u'accounts.google.com',
 u'sub': u'123456789',  # Fake Data
 u'token_hash': u'xxxyyyzzz',  # Fake Data
 u'verified_email': u'true'}

and the third segment is a combination of the first two signed with Google's private key.