首页 > 解决方案 > 403 禁止 - cloud_storage_bucket get_media

问题描述

import json
from httplib2 import Http
from oauth2client.client import SignedJwtAssertionCredentials
from googleapiclient.discovery import build

json_file = 'my.json'
client_email = json.loads(open(json_file).read())['client_email']
private_key = json.loads(open(json_file).read())['private_key']

cloud_storage_bucket = 'my_bucket'
report_to_download = 'sales/salesreport_201907.zip'

credentials = SignedJwtAssertionCredentials(client_email, private_key,['https://www.googleapis.com/auth/devstorage.read_only','https://www.googleapis.com/auth/devstorage.read_write','https://www.googleapis.com/auth/devstorage.full_control'])
storage = build('storage', 'v1', http=credentials.authorize(Http()))
object_metadata = storage.objects().get(bucket = cloud_storage_bucket, object = report_to_download).execute()
object_content = storage.objects().get_media(bucket = cloud_storage_bucket, object = report_to_download).execute()

我可以读取 object_metadata,但是在请求对象内容时,我得到:

googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/storage/v1/b/my_bucket/o/sales%2Fsalesreport_201907.zip?alt=media returned "Forbidden">

如您所见,我在凭据部分添加了三个范围,只是为了确保拥有所有权限。尽管如此,我仍然收到错误消息。

我正在使用 Python 2.7。

编辑:

我尝试使用 gsutil 下载文件并且它可以工作。所以它与权限无关。

编辑2:

更改了代码以使用非弃用库。

from logs import logger
import google.auth
import google.auth.transport.requests as tr_requests
from google.resumable_media.requests import Download
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="my.json"

ro_scope=u'https://www.googleapis.com/auth/devstorage.full_control'
credentials,_ = google.auth.default(scopes=(ro_scope,))
transport = tr_requests.AuthorizedSession(credentials)

cloud_storage_bucket = 'pubsite_prod_rev_xxxx'
report_to_download = 'sales/salesreport_201907.zip'

#option 1
media_url='https://www.googleapis.com/download/storage/v1/b/pubsite_prod_rev_xxxx/o/sales%2Fsalesreport_201907.zip?generation=1234&alt=media'
#option 2
media_url='https://www.googleapis.com/storage/v1/b/pubsite_prod_rev_xxxx/o/sales%2Fsalesreport_201907.zip'

download = Download(media_url)
response = download.consume(transport)
print download.finished

当使用选项 1 url 运行代码时,status is 200但这response.content只是元数据,之前使用该get方法发生过。

运行选项 2 时,如get_media方法,错误仍然存​​在403

  File "/anaconda2/envs/enviro27/lib/python2.7/site-packages/google/resumable_media/_helpers.py", line 93, in require_status_code
    status_code, u'Expected one of', *status_codes)
google.resumable_media.common.InvalidResponse: (u'Request failed with status code', 403, u'Expected one of', 200, 206)

此代码的文档

标签: pythonpython-2.7google-cloud-platformcloudgoogle-cloud-storage

解决方案


解决方案是发现真正的管理员帐户。尽管 Google Play 在一封电子邮件中显示了联系信息(我们认为是管理员的那一封),但真正的管理员是另一个帐户。找到它后,我们应用了这里解释的所有过程。

使用此代码,我们可以访问内容:

from logs import logger
import google.auth
import google.auth.transport.requests as tr_requests
from google.resumable_media.requests import Download
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="my.json"

ro_scope=u'https://www.googleapis.com/auth/devstorage.full_control'
credentials,_ = google.auth.default(scopes=(ro_scope,))
transport = tr_requests.AuthorizedSession(credentials)

cloud_storage_bucket = 'pubsite_prod_rev_xxxx'
report_to_download = 'sales/salesreport_201907.zip'

#option 1
media_url='https://www.googleapis.com/download/storage/v1/b/pubsite_prod_rev_xxxx/o/sales%2Fsalesreport_201907.zip?generation=1234&alt=media'
#option 2
media_url='https://www.googleapis.com/storage/v1/b/pubsite_prod_rev_xxxx/o/sales%2Fsalesreport_201907.zip'

download = Download(media_url)
response = download.consume(transport)
print download.finished

推荐阅读