0

I'm trying to do a web application using the OAuthlib to login with google, this is what the google object looks like:

google = oauth.remote_app('google',
    request_token_url=None,
    access_token_method='POST',
    request_token_params={'scope': 'email'},
    access_token_url='https://accounts.google.com/o/oauth2/token',
    authorize_url='https://accounts.google.com/o/oauth2/auth',
    consumer_key="my consumer",
    consumer_secret="my secret",
    base_url='https://www.googleapis.com/oauth2/v1/'
)

The problem I hve is when I get the user information from google, his is my authorization view:

@app.route('/login/authorized/<provider>')
def authorized():
    resp = google.authorized_response()
    auth_error(resp)
    id_token = json.load(resp['id_token'])
    login_user(me, True)
    return redirect(url_for('index'))

So, what I try to do with the json.load is to decode the information google gives me, in this particular case, the response has an id_token which is a long string that, according to my research, is a json encoded string that when it is decoded, provides all the user information, no matter how much I try I can't seem to find the correct way to decode it, the error I get is:

AttributeError: 'unicode' object has no attribute 'read'

On the json.load line.

EDIT: after decoding the id_token I would then use it to get or create the user in my own database.

I am using Flask and the library is json.

If anyone could explain the correct way to decode the string into a python object I would appreciate it a lot, or if this is not json but some other type of coded string please do tell. Thank you very much in advance.

2 Answers2

3

json.load reads from a file. To decode a JSON string, use json.loads.

However, according to these docs, id_token is not JSON, but a "JSON Web Token".

If you are looking for the "payload", you might try:

payload = json.loads( resp['id_token'].split('.')[1].decode('base64') )
A. Vidor
  • 2,502
  • 1
  • 16
  • 24
  • if I use json.loads I get ValueError: No JSON object could be decoded, maybe I'm not explaining very well what google is returning, I would post it here but it is a very, very long string, – Jenaro Calviño May 25 '16 at 23:18
  • @JenaroCalviño If the token looks like [base64](https://en.wikipedia.org/wiki/Base64) encoding, try decoding it first, as per my answer. – A. Vidor May 25 '16 at 23:22
  • @JenaroCalviño Can you please provide your research that suggests the `id_token` is a JSON string? – A. Vidor May 25 '16 at 23:33
  • this is the [link](http://stackoverflow.com/questions/8311836/how-to-identify-a-google-oauth2-user/13016081#13016081) taht suggests it is json, I printed the type of resp['id_token'] and it says it is unicode, and apparently decode('unicode') is not allowed – Jenaro Calviño May 25 '16 at 23:38
  • @JenaroCalviño Please see my revised answer. "JSON Web Tokens" are not simple JSON, but three base64-encoded JSON strings. See further, the documentation linked in my answer at [https://jwt.io/](https://jwt.io/introduction/). – A. Vidor May 25 '16 at 23:41
  • thank you, that is correct, apparently if I paste my id_token in that webpage it decodes it, I'm reading now how I can decode it in my code – Jenaro Calviño May 25 '16 at 23:48
  • @JenaroCalviño I mis-spoke in my previous comment. The third string in a JWT, although base64-encoded, is not JSON, but a signature used to verify the previous two strings. – A. Vidor May 25 '16 at 23:51
0

As @this-vidor said my id_token was a JWT not JSON, and I was finally able to decode it using a library called jwt, I used jwt.decode(resp['id_token'], verify=False) and it worked! Just posting this in case anyone had the same problem and wanted a solution. Thank you very much.

For more information on JWT