Я пытаюсь создать подписанный URL-адрес для объекта, хранящегося в Google Cloud Storage (GCS).
Попытка 1: попробуйте API с помощью API Explorer
. Для этого я пытаюсь подписать BLOB-объект / объект, как указано ниже:
GET
<expiration time>
/<bucket name>/<object/blob name>
IСначала попробовал Google serviceAccounts.signBlob API, как обсуждалось на следующей странице:
https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signBlob
Строка в кодировке base64.
Обратите внимание, что, как упоминалось в документации API на указанной выше странице, я передаю API-представление в виде base64, которое я хочу подписать.
Ответ API имеет следующую структуру:содержит ключ signedBlob
:
{
"keyId": "...",
"signedBlob": "..."
}
, затем я сгенерировал подписанный URL-адрес с использованием полученного подписанного большого двоичного объекта следующим образом:
encoded_signedBlob = base64.b64encode(signedBlob)
signed_url = "https://storage.googleapis.com/{}/{}?" \
"GoogleAccessId={}&" \
"Expires={}&" \
"Signature={}".format(
bucket_name, blob_name,
service_account_email,
expiration,
encoded_signedBlob)
и когда я вставляю этот подписанный URL-адрес в браузерЧтобы загрузить BLOB-объект, я получаю следующую ошибку:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.
</Message>
<StringToSign>GET <bucket name> <blob/object name></StringToSign>
</Error>
Попытка 2: попробуйте библиотеки Python
Затем я попытался реализовать его в Python, как показано ниже, но все равно получаю ту же ошибку.
# -------------
# Part 1: obtain access token using the authorization flow discussed at:
# https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials
# -------------
client_service_account = "..."
access_token = build(
serviceName='iamcredentials',
version='v1',
http=http
).projects().serviceAccounts().generateAccessToken(
name="projects/{}/serviceAccounts/{}".format(
'-',
service_account_email),
body=body
).execute()["accessToken"]
credentials = AccessTokenCredentials(access_token, "MyAgent/1.0", None)
# -------------
# Part 2: sign the blob
# -------------
service = discovery.build('iam', 'v1', credentials=credentials)
name = 'projects/.../serviceAccounts/...'
encoded = base64.b64encode(blob)
sign_blob_request_body = {"bytesToSign": encoded}
request = service.projects().serviceAccounts().signBlob(name=name, body=sign_blob_request_body)
response = request.execute()
keyId = response["keyId"]
signedBlob = response["signature"]
# -------------
# Part 3: generate signed URL
# -------------
encoded_signedBlob = base64.b64encode(signedBlob)
signed_url = "https://storage.googleapis.com/{}/{}?" \
"GoogleAccessId={}&" \
"Expires={}&" \
"Signature={}".format(
bucket_name, blob_name,
service_account_email,
expiration,
encoded_signedBlob)