Search code examples
python-2.7google-app-enginejwtgoogle-cloud-endpoints

Making Authorized Calls to an Google Cloud Endpoints API


My Current Setup

The echo tutorial is up and running. I can make calls to open endpoints and the one requiring an API key using a python script on my machine. I have not been able to make an authorized API call with a Google ID token. None of the Google examples have worked so far.

From my understanding, the workflow should be

  1. Use a key file to authorize the service account to generate a JWT.
  2. Use the JWT to generate a Google ID token.

Google Example: https://cloud.google.com/endpoints/docs/openapi/service-account-authentication#using_a_google_id_token (Key File) The code fails. Function get_id_token() return res['id_token'] fails with no id_token in res.

Has anyone gotten the example to work? Does anyone have an example of making an authorized API call to an Endpoint API with a Google ID token from a service account?


Solution

  • The main issue was generating the JWT and the code that works for me is below. I have yet to find a better way to do this that works. If you know of a better way please submit your answers below or add a comment. The code that generates the Google ID Token from JWT is exactly from Google documentation here (https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/endpoints/getting-started/clients/service_to_service_google_id_token/main.py) get_id_token function.

    def generate_jwt(audience, json_keyfile, service_account_email):
    """Generates a signed JSON Web Token using a Google API Service Account.
        https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/endpoints/getting-started/clients/google-jwt-client.py
    """
    
    # Note: this sample shows how to manually create the JWT for the purposes
    # of showing how the authentication works, but you can use
    # google.auth.jwt.Credentials to automatically create the JWT.
    #   http://google-auth.readthedocs.io/en/latest/reference/google.auth.jwt.html#google.auth.jwt.Credentials
    
    signer = google.auth.crypt.RSASigner.from_service_account_file(json_keyfile)
    
    now = int(time.time())
    expires = now + 3600  # One hour in seconds
    
    payload = {
        'iat': now,
        'exp': expires,
        'aud': 'https://www.googleapis.com/oauth2/v4/token',
        # target_audience must match 'audience' in the security configuration in your
        # openapi spec. It can be any string.
        'target_audience': audience,
        'iss': service_account_email
    }
    
    jwt = google.auth.jwt.encode(signer, payload)
    
    return jwt