1

After failing to authenticate for Google Server to Server Applications using Python Oauthlib, I am now trying to generate directly the jwt with pyjwt then test it with curl as stated in Google documentation, but it does not work either since I now receive: Invalid JWT: Token must be a short-lived token and in a reasonable timeframe.

The code in Python 3 after installing pyjwt:

>>> from datetime import datetime, timedelta

>>> import json
>>> import jwt

>>> json_file = json.load(open("google-project-credentials.json"))
>>> dt_now = datetime.datetime.utcnow()
>>> payload = { 'iss' : json_file['client_email'], 'scope' : 'https://www.googleapis.com/auth/tasks', 'aud' : 'https://www.googleapis.com/oauth2/v4/token', 'exp' : int((dt_now + datetime.timedelta(hours=1)).timestamp()), 'iat': int(dt_now.timestamp()) }
>>> jwt.encode(payload, json_file['private_key'], algorithm='RS256')
b'PYJWT_RESULT_HERE'

Then, as stated in Google documentation, I run curl in bash and paste the previous result:

$ curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=PYJWT_RESULT_HERE' https://www.googleapis.com/oauth2/v4/token

Then I receive the following error:

{
  "error": "invalid_grant",
  "error_description": "Invalid JWT: Token must be a short-lived token and in a reasonable timeframe"
}

What am I doing wrong?

Thanks!

Community
  • 1
  • 1
Antoine Brunel
  • 1,065
  • 2
  • 14
  • 30

1 Answers1

1

Actually, as stated in the error message, the problem was in the epoch that was incorrectly generated (I don't completely understand why yet):

>>> from datetime import datetime
>>> from calendar import timegm
>>> import json
>>> import jwt

>>> json_file = json.load(open("google-project-credentials.json"))
>>> payload = { 'iss' : json_file['client_email'], 'scope' : 'https://www.googleapis.com/auth/tasks', 'aud' : 'https://www.googleapis.com/oauth2/v4/token', 'exp' : timegm(datetime.utcnow().utctimetuple()) + 600, 'iat' : timegm(datetime.utcnow().utctimetuple()) }
>>> jwt.encode(payload, json_file['private_key'], algorithm='RS256')
b'PYJWT_RESULT_HERE'

Then in a Bash console:

$ curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=PYJWT_RESULT_HERE' https://www.googleapis.com/oauth2/v4/token
{
  "access_token": "GOOGLE_ACCESS_TOKEN_YEAH",
   "token_type": "Bearer",
   "expires_in": 3600
}

I was actually surprised not to receive more help on that matter since I thought Google would be involved ;-( On open-source project, the support is actually better!

Antoine Brunel
  • 1,065
  • 2
  • 14
  • 30