如何解决非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
相关产品推荐
相关产品推荐

