You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决非App Engine环境下django-storages对接Google Cloud Storage的403错误

解决Django连接Google Cloud Storage时的403权限拒绝错误

问题背景

我没有使用App Engine,参考教程安装了django-storages和boto,在settings.py中做了如下配置:

DEFAULT_FILE_STORAGE = 'storages.backends.gs.GSBotoStorage'
GS_ACCESS_KEY_ID = '***@***.iam.gserviceaccount.com'
GS_SECRET_ACCESS_KEY = '***'
GS_BUCKET_NAME = '***'
STATICFILES_STORAGE = 'storages.backends.gs.GSBotoStorage'

执行以下代码时触发了403权限错误:

from django.core.files.storage import default_storage
default_storage.exists('storage_test')

报错信息如下:

---------------------------------------------------------------------------
GSResponseError                            Traceback (most recent call last)
<ipython-input-2-8a49776d7c1d> in <module>()
      1 from django.core.files.storage import default_storage
----> 2 default_storage.exists('storage_test')

/Users/trmt_8/.pyenv/versions/3.5.0/lib/python3.5/site-packages/storages/backends/s3boto.py in exists(self, name)
    433             return False
    434 
--> 435         return self._get_key(name) is not None
    436 
    437     def listdir(self, name):

/Users/trmt_8/.pyenv/versions/3.5.0/lib/python3.5/site-packages/storages/backends/s3boto.py in _get_key(self, name)
    419         if self.entries:
    420             return self.entries.get(name)
--> 421         return self.bucket.get_key(self._encode_name(name))
    422 
    423     def delete(self, name):

/Users/trmt_8/.pyenv/versions/3.5.0/lib/python3.5/site-packages/boto/gs/bucket.py in get_key(self, key_name, headers, version_id, response_headers, generation)
    109         try:
    110             key, resp = self._get_key_internal(key_name, headers,
--> 111                                                query_args_l=query_args_l)
    112         except GSResponseError as e:
    113             if e.status == 403 and 'Forbidden' in e.reason:

/Users/trmt_8/.pyenv/versions/3.5.0/lib/python3.5/site-packages/boto/s3/bucket.py in _get_key_internal(self, key_name, headers, query_args_l)
    230         else:
    231             raise self.connection.provider.storage_response_error(
--> 232                 response.status, response.reason, '')
    233 
    234     def list(self, prefix='', delimiter='', marker='', headers=None,

GSResponseError: GSResponseError: 403 Access denied to 'gs://***/storage_test'.

解决步骤

1. 检查服务账号的权限配置

首先确认你使用的IAM服务账号(GS_ACCESS_KEY_ID里的账号)拥有Google Cloud Storage的读写权限:

  • 登录Google Cloud控制台,找到对应的服务账号
  • 给它添加Storage Object Admin或Storage Admin角色(如果需要全桶管理的话)
  • 注意:不要只给Storage Object Viewer,因为exists操作需要读取桶内对象的权限,写入操作还需要更多权限

2. 验证密钥的正确性

确保GS_SECRET_ACCESS_KEY是该服务账号的正确私有密钥:

  • 如果你是通过JSON密钥文件获取的,注意不要复制错误,密钥是一段长字符串,没有换行或多余字符
  • 可以尝试重新生成服务账号的密钥,替换现有配置中的GS_SECRET_ACCESS_KEY

3. 检查Bucket的权限设置

确认你的Bucket没有设置过于严格的权限策略,阻止了服务账号访问:

  • 进入Bucket的权限页面,检查是否有针对该服务账号的明确允许规则
  • 如果Bucket启用了Uniform Bucket Level Access,确保服务账号的角色已经覆盖了桶级权限

4. 确认django-storages和boto的版本兼容性

旧版本的django-storages或boto可能存在GCS适配问题:

  • 尝试更新到最新稳定版:
pip install --upgrade django-storages boto
  • 另外,也可以尝试使用boto3替代旧的boto,部分新版本的django-storages推荐使用boto3

5. 添加额外的配置参数(可选)

在settings.py中添加以下配置,确保连接正确指向GCS:

GS_ENDPOINT = 'https://storage.googleapis.com'
GS_LOCATION = 'us-central1'  # 替换为你的Bucket所在区域

6. 测试基础连接

可以先不通过Django,直接用boto测试连接:

import boto
from boto.gs.connection import GSConnection

conn = GSConnection(
    aws_access_key_id='你的服务账号ID',
    aws_secret_access_key='你的密钥'
)
bucket = conn.get_bucket('你的Bucket名称')
# 尝试列出桶内对象
for key in bucket.list():
    print(key.name)

如果这段代码也报错,说明问题出在GCS的权限或密钥配置,而非Django层面


内容的提问来源于stack exchange,提问作者Nori

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:26:40