简体   繁体   中英

Create access token for Google Bigquery using JWT with python

I am trying to get access token for bigquery using JWT method with python. New access token will be used to access bigquery. But while trying to get new access token it is showing error 401. I am not sure how to resolve this error. Following files I have used to create the scenario.

jwt.py

import google.auth.jwt as jwt
import google.auth.crypt
import time
import json
import requests


now = int(time.time())
sa_email = ''# service account
audience = 'https://www.googleapis.com/auth/bigquery'
sa_keyfile = 'key.json'
# build payload
payload = {
    'iat': now,
    # expires after 'expiry_length' seconds.
    "exp": now + 3600,
    'iss': sa_email,
    'aud': audience,
    'sub': sa_email,
    'email': sa_email
}

# sign with keyfile
signer = google.auth.crypt.RSASigner.from_service_account_file(sa_keyfile)
jwt = google.auth.jwt.encode(signer, payload)
print(jwt)
headers = {
        'Authorization': 'Bearer {}'.format(jwt.decode('utf-8')),
        'Content-type': 'application/json',
        'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer'
    }

url = 'https://www.googleapis.com/bigquery/v2/projects'
response = requests.get(url, headers=headers)
print(response)
print(response.status_code, response.content)
token = response.json()['access_token']
print('token : ', token)
response.raise_for_status()

requirements.txt

asttokens==2.0.5
backcall==0.2.0
cachetools==5.2.0
certifi==2022.6.15
charset-normalizer==2.1.0
click==8.1.3
debugpy==1.6.2
decorator==5.1.1
entrypoints==0.4
executing==0.8.3
Flask==2.1.2
google-auth==2.9.1
idna==3.3
importlib-metadata==4.12.0
ipykernel==6.15.1
ipython==8.4.0
itsdangerous==2.1.2
jedi==0.18.1
Jinja2==3.1.2
jupyter-client==7.3.4
jupyter-core==4.11.1
MarkupSafe==2.1.1
matplotlib-inline==0.1.3
nest-asyncio==1.5.5
packaging==21.3
parso==0.8.3
pexpect==4.8.0
pickleshare==0.7.5
prompt-toolkit==3.0.30
psutil==5.9.1
ptyprocess==0.7.0
pure-eval==0.2.2
pyasn1==0.4.8
pyasn1-modules==0.2.8
Pygments==2.12.0
pyparsing==3.0.9
python-dateutil==2.8.2
pyzmq==23.2.0
requests==2.28.1
rsa==4.8
six==1.16.0
stack-data==0.3.0
tornado==6.2
traitlets==5.3.0
urllib3==1.26.10
wcwidth==0.2.5
Werkzeug==2.1.2
zipp==3.8.0

But I am getting this error :

<Response [401]>
401 b'{\n  "error": {\n    "code": 401,\n    "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",\n    "errors": [\n      {\n        "message": "Invalid Credentials",\n        "domain": "global",\n        "reason": "authError",\n        "location": "Authorization",\n        "locationType": "header"\n      }\n    ],\n    "status": "UNAUTHENTICATED"\n  }\n}\n'
token :  {'error': {'code': 401, 'message': 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.', 'errors': [{'message': 'Invalid Credentials', 'domain': 'global', 'reason': 'authError', 'location': 'Authorization', 'locationType': 'header'}], 'status': 'UNAUTHENTICATED'}}
Traceback (most recent call last):
  File "test4.py", line 39, in <module>
    response.raise_for_status()
  File "/workspace/datastudio-poc/.env/lib/python3.8/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://www.googleapis.com/bigquery/v2/projects

Please suggest something and thank you in advance.

JWT tokens are used to authenticate users in GCP where a client application sends JSON Web Token for authentication. For creating JWT tokens, you can follow this documentation .

According to the error mentioned, you can first try validating the JWT token whether the token contains valid JSON or not for which you can use jwt.io . You need to make an authenticated request to API by creating a JWT and sign it with service accounts private key and send the signed JWT as a request to the API. For more details, you can check this link .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM