There are ways to use the gcloud API and SDK to run the GCP API.
Use a service account created with GCP. Since there is OAuth 2.0 authentication, API is accessed after getting a token. However, there was also a method of requesting the API directly without taking a token by encrypting the authentication information and embedding it in the http request header. I think that the latter is more familiar with how to make JWT, so this time I will use it.
The OS used was CentOS7 of Linux. In this article, we will skip creating service accounts. Please see https://jwt.io/introduction/ for details.
(Reference: Call using HTTP / REST https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests: How to call API directly https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth)
Google APIs GitHub repository seems to be unavailable if there is no API definition file you want to use. In this article, we will call the logging API. About logging API https://github.com/googleapis/googleapis/blob/master/google/logging/logging.yaml I was able to confirm it.
- Summarize the information required for authentication
- Create JSON Web Token (JWT) from 1.
- Calling GCP API using JWT
I want to call GCP API in curl like this.
Item | Input Value |
---|---|
iss | value of client_email in service account authentication file (JSON) |
sub | value of client_email in service account authentication file (JSON) |
aud | Create it like "https: // SERVICE_NAME / API_NAME". In this case, SERVICE_NAME and API_NAME are in https://github.com/googleapis/googleapis/blob/master/google/logging/logging.yaml. |
iat | The time when the assertion was issued. It is specified in seconds since January 1, 1970 00:00:00 UTC. |
exp | The expiration date of the assertion. Specified as the number of seconds since 00:00:00 UTC on January 1, 1970. This value is a maximum of one hour after the issue time. ** The token you create has an expiration date. The deadline is up to 1 hour. ** |
kid | private_key_id in JSON of service account authentication information |
Reference: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
Use Python 2.7.5. Install using pip.
python get-pip.py
pip install pyjwt
pip install cryptography
Complete the python code based on the https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth code. ** signed_jwt ** is output, so copy it.
#-*-coding: utf-8-*-
import jwt
import time
iat = time.time ()
exp = iat + 3600
payload = {'iss': 'stackdriver-logging-read @ xxxxx-xxxxx-xxxx..iam.gserviceaccount.com',
'sub': 'stackdriver-logging-read@xxxxx-xxxxx-xxxx.iam.gserviceaccount.com',
'aud': 'https://logging.googleapis.com/google.logging.v2.LoggingServiceV2',
'iat': iat,
'exp': exp}
additional_headers = {'kid': 'XXXXXXXXXXXXX'}
signed_jwt = jwt.encode (payload, '----- BEGIN PRIVATE KEY ----- \ nXXXXXXXXXXXXXXXXXXXXXXXXXXX \ n ----- END PRIVATE KEY ----- \ n', headers = additional_headers, algorithm = ' RS256 ')
print signed_jwt
Check the GCP [manual page] (https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries/list) for the URI to specify for curl, or use --log- If you run with http, you can see below.
gcloud logging read 'timestamp <= "2019-07-30T23: 59: 59Z"' --format = "json" --log-http
...
==== request start ====
uri: https://logging.googleapis.com/v2/entries:list?alt=json
method: POST
...
The curl command is as follows. Please put ** signed_jwt ** made with python and GCP project-name appropriately.
curl -X POST \
'https://logging.googleapis.com/v2/entries:list?alt=json' \
-H 'Authorization: Bearer <signed_jwt>' \
-H 'Content-Type: application / json' \
-H 'Host: logging.googleapis.com' \
-d '{"filter":' \ '' timestamp <= "2019-07-30T23: 59: 59Z" '\' ', "orderBy": "timestamp desc", "pageSize": 1000, "resourceNames": ["projects / <project-name>"]} '
-
- As I wrote in the exp section of creating authentication information (JWT), the token has an expiration date. If it expires, you must create signed_jwt again. *
The output is as follows. Same as when executing gcloud command.
{
"entries": [
{
"insertId": "............................. Aj_ ..",
"jsonPayload": {
"client.received.end.timestamp": "1564465946852",
"request.verb": "GET",
...
`` `
## Supplement
JWT was generated with a python tool, but I also examined how to generate it with Linux commands
JWT
-Header
-Payload
-Signature
Consists of
base64UrlEncode (header) + "." + base64UrlEncode (payload) + "." + Signature
Signature is
base64UrlEncode (header) + "." + base64UrlEncode (payload)
Signed with a private key and base64UrlEncode.
The private key is in the GCP service account credentials (json).
A string starting with ----- BEGIN PRIVATE KEY -----. Copy this and create a text file (secret_key).
```shell
header = '{
"alg": "RS256",
"typ": "JWT",
"kid": "0123456789abcdef01234567"
} '
payload = '{
"iss": "[email protected]",
"iat": 1565869581.475549,
"sub": "[email protected]",
"exp": 1565873181.475549,
"aud": "https://logging.googleapis.com/google.logging.v2.LoggingServiceV2"
} '
base64UrlEncHeader = `echo -n $ {header} | tr -d" \ n "| openssl base64 | tr-'+ / =' '-_' | tr -d" \ n "`
base64UrlEncPayload = `echo -n $ {payload} | tr -d" \ n "| openssl base64 | tr-'+ / =' '-_' | tr -d" \ n "`
signature = `echo -n" $ {base64UrlEncHeader}. $ {base64UrlEncPayload} "| openssl dgst -sha256 -sign secret_key -binary | openssl base64 | tr-'+ / =' '-_' | tr -d" \ n "`
echo "$ {base64UrlEncHeader}. $ {base64UrlEncPayload}. $ {signature}"
[reference] https://jwt.io/introduction/ https://qiita.com/kunichiko/items/3c0b1a2915e9dacbd4c1 https://crypto.stackexchange.com/posts/68400/revisions