首页 文章

来自GAE - 403 Access的 Cloud 存储API请求未配置

提问于
浏览
2

我的GAE应用正试图操纵存储在Google Cloud 端存储上的文件 .

这些文件存储在我的应用程序的默认存储桶中 . 我已经设法使用GCS Python客户端库(https://developers.google.com/appengine/docs/python/googlecloudstorageclient/)读取/写入该文件桶 .

不幸的是它不支持复制 . 相反,我正在尝试使用API客户端库(https://google-api-client-libraries.appspot.com/documentation/storage/v1/python/latest/storage_v1.objects.html)和服务帐户(https://developers.google.com/api-client-library/python/guide/google_app_engine#ServiceAccounts)的JSON API

到目前为止,我在请求 Cloud 存储网址时收到错误403 .

这是代码:

credentials = AppAssertionCredentials(scope='https://www.googleapis.com/auth/devstorage.read_write')
http = credentials.authorize(httplib2.Http(memcache))
service = discovery.build('storage', 'v1', http=http, developerKey='api_key_generated_from_the_dev_console')
bucket_name = app_identity.get_default_gcs_bucket_name()

# I'm planning to batch multiple requests, although there is just one in this example
batch = BatchHttpRequest()

# process_list_response outputs the exception if any
batch.add(service.objects().list(bucket=bucket_name), callback=process_list_response) 
batch.execute(http=http)

这是日志:

请求的URL:https://www.googleapis.com/discovery/v1/apis/storage/v1/rest?userIp = xxxx尝试刷新以获取所请求的初始access_token URL:https://www.googleapis.com/请求https://www.googleapis.com/storage/v1/b/xxx-dev.appspot.com/o?alt=json时存储/ v1 / b / xxx.appspot.com / o?alt = json HttpError 403返回“未配置访问权限 . 请使用Google Developers Console激活项目的API . ”

这是我在开发控制台中所做的:

  • Google Cloud 端存储和Google Cloud 存储JSON API已切换为开启 .

  • 我创建了一个用于构建服务的API密钥(是否有必要,因为我也使用Oauth?)

  • 在权限下,我为我的应用添加了一个成员,电子邮件为xxx@appspot.gserviceaccount.com

我怎样才能做到这一点?

1 回答

  • 1

    将此作为答案发布,因为我的编辑(我们一起工作)似乎被默默拒绝,评论太有限了 . 这不是一个答案,但这正在扩大这个问题 .

    使用单个http请求的更简单示例 . 看起来JSON API根本不在API资源管理器之外工作 . XML / REST API工作并返回存储桶中的文件列表 .

    credentials = AppAssertionCredentials(scope='https://www.googleapis.com/auth/devstorage.read_write')
    http = credentials.authorize(httplib2.Http(memcache))
    
    bucket_name = app_identity.get_default_gcs_bucket_name()
    
    # This works (200 with list of files in the content)
    request_url = 'http://commondatastorage.googleapis.com/' + bucket_name
    response, content = http.request(request_url, method="GET")
    
    # This doesn't work (403, Access not configured)
    request_url = 'https://www.googleapis.com/storage/v1/b/' + bucket_name + '/o?alt=json'
    response, content = http.request(request_url, method="GET")
    
    # This doesn't work (403, Access not configured), the key and project id header seem useless.
    request_url = 'https://www.googleapis.com/storage/v1/b/' + bucket_name + '/o?alt=json&key=' + API_KEY
    response, content = http.request(request_url, method="GET", headers={'x-goog-project-id': PROJECT_ID})
    

    另外,查看AppAssertionCredentials的代码,我们可以看到:

    kwargs: optional keyword args, including:
        service_account_id: service account id of the application. If None or
          unspecified, the default service account for the app is used.
    
    self.service_account_id = kwargs.get('service_account_id', None)
    

    将任何内容作为service_account_id参数传递会导致异常:

    Traceback (most recent call last):
      File "/base/data/home/apps/.../1.37.../backup.py", line 61, in get
        response, content = http.request(request_url, method="GET")
      File "/base/data/home/apps/.../1.377.../oauth2client/util.py", line 132, in positional_wrapper
        return wrapped(*args, **kwargs)
      File "/base/data/home/apps/.../1.37.../oauth2client/client.py", line 491, in new_request
        self._refresh(request_orig)
      File "/base/data/home/apps/.../1.37.../oauth2client/appengine.py", line 197, in _refresh
        raise AccessTokenRefreshError(str(e))
    AccessTokenRefreshError
    

    我已经测试过传递 app_identity.get_service_account_name() 返回的值,但这不起作用 . (即使文档说如果没有设置它将使用"the default service account for the app") .

    我已经测试过传递开发人员控制台中找到的服务帐户电子邮件,其中包含以下格式: 3....-v0....@developer.gserviceaccount.com . 相同的令牌异常 .

    那么,当我们的api / services明确启用Cloudstorage JSON API时,为什么我们没有配置403 Access?

    为什么使用AccessTokenRefreshError将service_account_id传递给AppAssertionCredentials失败?

    编辑:

    The solution was ridiculous: turn OFF the Google Cloud Storage API, and turn it back ON.

    我假设该应用程序是一个"legacy"应用程序,这样做使得最后一个要点12在这里工作:https://developers.google.com/appengine/docs/python/googlecloudstorageclient/activate

相关问题