簡體   English   中英

帶有 django-storages 的 ImageField 導致:“解析 X-Amz-Credential 參數時出錯;區域‘us-east-1’錯誤;期待‘us-west-1’”

[英]ImageField with django-storages leads to: "Error parsing the X-Amz-Credential parameter; the region 'us-east-1' is wrong; expecting 'us-west-1'"

我正在嘗試將一個ImageField添加到一個名為LucyGuide的 model 中,它將使用django-storages storages 將用戶上傳的圖像保存到 S3。 這是(簡化的)model:

class LucyGuide(TimeStampedModel):
    headshot = models.ImageField(upload_to='uploads/', null=True)
    bio = models.TextField(blank=True)

我已將以下內容添加到我的settings.py

# Use Boto3 backend to interact with Amazon's S3
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

# Amazon S3 credentials (for django-storages)
AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID', default='')
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY', default='')

AWS_STORAGE_BUCKET_NAME = os.getenv('AWS_STORAGE_BUCKET_NAME', default='')
AWS_S3_REGION_NAME = os.getenv('AWS_S3_REGION_NAME')
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}
# Use v4 of the signing protocol (recommended for all new projects)
AWS_S3_SIGNATURE_VERSION = 's3v4'

.env文件中讀取實際密鑰的位置(使用類似於django-decouple的機制)。

為了嘗試這一點,我在 Django 的管理 UI 中為LucyGuide上傳了一張隨機圖片:

在此處輸入圖像描述

在 shell 中,我可以訪問指南headshot字段的url屬性,這確實是一個 AWS 存儲桶的鏈接:

In [6]: guide = LucyGuide.objects.filter(bio__startswith="Kristen").first()

In [7]: guide
Out[7]: <LucyGuide: Kristen Hoover>

In [8]: guide.headshot
Out[8]: <ImageFieldFile: uploads/320px-Waaah.jpg>

In [9]: guide.headshot.url
Out[9]: 'https://lucy-prod.s3.amazonaws.com/uploads/320px-Waaah.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIMC2A%2F20180327%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20180327T200248Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=ae75dbdd75d13020113c12ef2d655e3'

(我刪除了部分 URL)。 問題是,當我嘗試在瀏覽器中將 go 轉換為 URL 時,出現“此 XML 文件似乎沒有與之關聯的任何樣式信息”錯誤:

<Error>
<Code>AuthorizationQueryParametersError</Code>
<Message>
Error parsing the X-Amz-Credential parameter; the region 'us-east-1' is wrong; expecting 'us-west-1'
</Message>
<Region>us-west-1</Region>
<RequestId>1E053D94011E400F</RequestId>
<HostId>
jbkRHVj2y6ygppTsAo2+uOXgby0ok0mbsFsRogKqbu9jPMb+9eGe24nJv441vip3WpmwpFqlsYg=
</HostId>
</Error>

在此處輸入圖像描述

我已經嘗試通過添加AWS_S3_REGION_NAME設置來解決這個問題(參見http://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html )。 錯誤消息指示的區域us-west-1似乎是正確的區域,因為存儲桶設置在“美國西部(加利福尼亞北部)”:

在此處輸入圖像描述

總而言之,盡管設置了正確的AWS_S3_REGION_NAME ,但我不明白為什么會發生此錯誤。 我該如何解決這個錯誤?

更新

如果我檢查存儲桶中的 object,我會發現它有一個“鏈接”,它比headshot字段的url屬性生成的鏈接簡單得多:

在此處輸入圖像描述

我正在考慮將此處顯示的“基本 URL”硬編碼到我試圖構建的用於檢索圖像 URL 的端點 API 中,但這似乎不是一個優雅的解決方案。 有更好的主意嗎?

您需要將變量 AWS_S3_REGION_NAME 添加到 settings.py。 它可能在您的 env 文件中丟失 另請參閱: https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html

通過閱讀(並在django-storages源代碼中設置斷點),我能夠通過添加設置來解決問題

AWS_QUERYSTRING_AUTH = False

從默認值True更改它。 現在, url屬性生成一個沒有身份驗證查詢字符串的URL:

In [2]: guide = LucyGuide.objects.filter(bio__startswith='Darrell').first()

In [3]: guide.headshot
Out[3]: <ImageFieldFile: uploads/Waaah.jpg>

In [4]: guide.headshot.url
Out[4]: 'https://lucy-prod.s3.amazonaws.com/uploads/Waaah.jpg'

無需關閉查詢字符串,您可以簡單地使用AWS_S3_REGION_NAME =''us-east-2''#將us-east-2替換為您的區域。 更安全。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM