web-dev-qa-db-fra.com

Comment obtenir un jeton GCP Bearer par programme avec python

gcloud auth print-access-token me donne un jeton porteur que je pourrai utiliser plus tard; cependant, il s'agit d'une commande Shell. Comment en obtenir un par programmation via Google Cloud Python API?

Je vois un exemple précédent utilisant oauth2client , mais oauth2client est désormais obsolète. Comment pourrais-je faire cela avec google.auth et oauthlib ?

10
indraniel

La réponse dépend de votre environnement et de la façon dont vous souhaitez créer/obtenir les informations d'identification.

Que sont les informations d'identification Google Cloud?

Les informations d'identification Google Cloud sont un jeton OAuth 2.0. Ce jeton a au minimum un Access Token Et éventuellement un Refresh Token, Client ID Token, Et un support des paramètres tels que expiration, Service Account Email ou Client Email, etc.

L'élément important dans les API Google Cloud est le Access Token. Ce jeton est ce qui autorise l'accès au cloud. Ce jeton peut être utilisé dans des programmes tels que curl, des logiciels tels que python, etc. et ne nécessite pas de SDK. Le Access Token Est utilisé dans l'en-tête HTTP Authorization.

Qu'est-ce qu'un jeton d'accès?

Un jeton d'accès est une valeur opaque générée par Google qui est dérivée d'un JWT signé, plus correctement appelé JWS. Un JWT se compose d'un en-tête et de revendications (la charge utile) des structures Json. Ces deux structures Json sont signées avec la clé privée du compte de service. Ces valeurs sont codées en base64 et concaténées pour créer la clé d'accès.

Le format d'un jeton d'accès est le suivant: base64(header) + '.' + base64(payload) + '.' + base64(signature).

Voici un exemple de JWT:

Entête:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "42ba1e234ac91ffca687a5b5b3d0ca2d7ce0fc0a"
}

Charge utile:

{
  "iss": "[email protected]",
  "iat": 1493833746,
  "aud": "myservice.appspot.com",
  "exp": 1493837346,
  "sub": "[email protected]"
}

en utilisant un jeton d'accès:

Exemple qui démarrera une instance VM. Remplacez PROJECT_ID, ZONE et INSTANCE_NAME. Cet exemple concerne Windows.

curl -v -X GET -H "Authorization: Bearer <access_token_here>" ^
https://www.googleapis.com/compute/v1/projects/%PROJECT_ID%/zones/%ZONE%/instances/%INSTANCE_NAME%/start

Compte de service Compute Engine:

La réponse de Dustin est correcte pour ce cas, mais je vais inclure pour être complet avec quelques informations supplémentaires.

Ces informations d'identification sont automatiquement créées pour vous par GCP et sont obtenues à partir des métadonnées d'instance VM. Les autorisations sont contrôlées par Cloud API access scopes Dans la console Google.

Cependant, ces informations d'identification ont certaines limites. Pour modifier les informations d'identification, vous devez d'abord arrêter l'instance VM. De plus, toutes les autorisations (rôles) ne sont pas prises en charge.

from google.auth import compute_engine

cred = compute_engine.Credentials()

Informations d'identification du compte de service:

Jusqu'à ce que vous compreniez tous les types d'informations d'identification et leurs cas d'utilisation, ce sont les informations d'identification que vous utiliserez pour tout sauf pour gcloud et gsutil. La compréhension de ces informations d'identification rendra le travail avec Google Cloud beaucoup plus simple lors de l'écriture de programmes. Obtenir des informations d'identification à partir d'un fichier Json de compte de service Google est facile. Le seul élément à noter est que les informations d'identification expirent (généralement 60 minutes) et doivent être actualisées ou recréées.

gcloud auth print-access-token N'est PAS recommandé. Les informations d'identification du compte de service sont la méthode recommandée par Google.

Ces informations d'identification sont créées par la console, gcloud ou via des programmes/API. Les autorisations sont attribuées aux créanciers par IAM et fonctionnent dans Compute Engine, App Engine, Firestore, Kubernetes, etc. ainsi que dans d'autres environnements en dehors de Google Cloud. Ces informations d'identification sont téléchargées à partir de Google Cloud et stockées dans un fichier Json. Notez le paramètre scopes. Cela définit les autorisations accordées à l'objet d'informations d'identification résultant.

SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
SERVICE_ACCOUNT_FILE = 'service-account-credentials.json'

from google.oauth2 import service_account

cred = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

Google OAuth 2.0 Informations d'identification:

Ces informations d'identification sont dérivées d'un flux complet OAuth 2.0. Ces informations d'identification sont générées lorsque votre navigateur est lancé pour accéder aux comptes Google pour autoriser l'accès. Ce processus est beaucoup plus compliqué et nécessite une bonne quantité de code à implémenter et nécessite un serveur Web intégré pour le rappel de l'autorisation.

Cette méthode fournit des fonctionnalités supplémentaires telles que la possibilité de tout exécuter dans un navigateur, par exemple, vous pouvez créer un navigateur de fichiers de stockage Cloud, mais veillez à bien comprendre les implications pour la sécurité. Cette méthode est la technique utilisée pour prendre en charge la connexion Google, etc. J'aime utiliser cette méthode pour authentifier les utilisateurs avant d'autoriser la publication sur des sites Web, etc. Les possibilités sont infinies avec une autorisation correctement autorisée OAuth 2.0 identités et portées.

Exemple de code utilisant google_auth_oauthlib:

from google_auth_oauthlib.flow import InstalledAppFlow

flow = InstalledAppFlow.from_client_secrets_file(
    'client_secrets.json',
    scopes=scope)

cred = flow.run_local_server(
    Host='localhost',
    port=8088,
    authorization_Prompt_message='Please visit this URL: {url}',
    success_message='The auth flow is complete; you may close this window.',
    open_browser=True)

Exemple de code utilisant la bibliothèque requests_oauthlib:

from requests_oauthlib import OAuth2Session

gcp = OAuth2Session(
        app.config['gcp_client_id'],
        scope=scope,
        redirect_uri=redirect_uri)

# print('Requesting authorization url:', authorization_base_url)

authorization_url, state = gcp.authorization_url(
                        authorization_base_url,
                        access_type="offline",
                        Prompt="consent",
                        include_granted_scopes='true')

session['oauth_state'] = state

return redirect(authorization_url)


# Next section of code after the browser approves the request

token = gcp.fetch_token(
            token_url,
            client_secret=app.config['gcp_client_secret'],
            authorization_response=request.url)
14
John Hanley

Bien que la réponse ci-dessus soit assez informative, il manque un point important - l'objet d'informations d'identification obtenu à partir de google.auth.default() ou compute_engine.Credentials() n'aura pas de jeton. Revenons donc à la question initiale de savoir quelle est l'alternative programmatique à gcloud auth print-access-token, ma réponse serait:

import google.auth
import google.auth.transport.requests
creds, projects = google.auth.default()

# creds.valid is False, and creds.token is None
# Need to refresh credentials to populate those

auth_req = google.auth.transport.requests.Request()
creds.refresh(auth_req)

# Now you can use creds.token

J'utilise le package google-auth officiel et informations d'identification par défaut , ce qui vous permettra de démarrer à la fois en développement local et sur l'application GCE/GKE distante.

Dommage que ce ne soit pas correctement documenté et j'ai dû lire google-auth code pour comprendre comment obtenir le jeton.

6
Zaar Hai

Je me suis retrouvé ici lorsque je cherchais un moyen d'utiliser le SDK python sans créer de compte de service. Je voulais un moyen de développer localement un script qui s'exécuterait dans le cloud. J'ai pu atteindre ceci en utilisant un artefact de la commande gcloud:

export GOOGLE_APPLICATION_CREDENTIALS=~/.config/gcloud/legacy_credentials/<me>/adc.json
0
schmitt