我的代码已成功将文档上传到正确的存储桶中。我可以登录并查看AWS S3上的文档。当我尝试使用boto3中的generate_signed_url方法获取这些文档的URL然后可以发送给用户访问文档时,我收到一个SignatureDoesNotMatch,其中显示的消息是"我们计算的请求签名与您提供的签名不符。检查您的密钥和签名方法。"
当我保存对象时(通过登录AWS并手动下载文件来验证它是否正常工作),我使用:
s3 = boto3.client('s3', region_name='us-east-2', aws_access_key_id='XXXX', aws_secret_access_key='XXXX', config=Config(signature_version='s3v4'))
s3.put_object(Bucket=self.bucket_name,Key=path, Body=temp_file.getvalue(),ACL='public-read')
然后,当我尝试获取网址时,我正在使用:
s3 = boto3.client('s3', region_name='us-east-2', aws_access_key_id='XXXX', aws_secret_access_key='XXXX', config=Config(signature_version='s3v4'))
url = s3.generate_presigned_url(
'put_object', Params={
'Bucket':self.pdffile_storage_bucket_name,
'Key':self.pdffile_url
},
ExpiresIn=604799,
)
我在网上看到很多用户在谈论确保您的AWS访问密钥不包含任何特殊字符。我这样做了,我仍然遇到同样的问题。
答案 0 :(得分:1)
您正在为上传而非下载生成预先签名的网址。你不想在这里put_object
......它是get_object
。
另外,正如@ThijsvanDien指出的那样,ACL='public-read'
可能不是您想要的,在上传时 - 这使得任何拥有未签名网址的人都可以访问该对象。
答案 1 :(得分:1)
(经过 3 个多小时的调试,差点把键盘砸坏....)
在响应中,它会告诉您缺少哪个标头:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
<!-- .... -->
<CanonicalRequest>PUT (your pre-signed url)
content-type:image/jpeg
host:s3.eu-west-2.amazonaws.com
x-amz-acl:
content-type;host;x-amz-acl
UNSIGNED-PAYLOAD</CanonicalRequest>
生成预签名 URL 时需要与 ACL 集匹配的 x-amz-acl
标头
def python_presign_url():
return s3.generate_presigned_url('put_object', Params={
'Bucket': bucket_name,
'Key': filename,
'ContentType': type,
'ACL':'public-read' # your x-amz-acl
})
curl -X PUT \
-H "content-type: image/jpeg" \
-H "Host: s3.eu-west-2.amazonaws.com" \
-H "x-amz-acl: public-read" \
-d @/path/to/upload/file.jpg "$PRE_SIGNED_URL"
答案 2 :(得分:0)
我尝试了来自许多不同地方的许多解决方案。没有一个对我有用。然后我在GitHub上找到了一个对我有用的解决方案。 Here是原始解决方案,只需复制粘贴其解决方案即可。
s3 = boto3.client('s3',region_name ='us-east-2', aws_access_key_id ='XXXX',aws_secret_access_key ='XXXX', config = Config(signature_version ='s3v4'), endpoint_url ='https://s3.us-east-2.amazonaws.com')