如何正确设置上传文件到DigitalOcean Spaces云存储的访问权限?

问题描述 投票:0回答:1

我正在通过 Python 脚本将文件上传到 DigitalOcean Spaces(AWS S3 兼容对象存储)。

上传文件运行良好;我不太确定的部分是如何正确访问这些文件。我必须设置

IMAGES_STORE_S3_ACL = 'public-read'

这样我就可以显示我上传到存储的图像。否则,我会看到

Permission Denied
错误。我显示文件的方式是连接文件的路径,类似于
file_path = f'{storage_domain}/my_files/{file_name}'

当我将此路径输入浏览器时,它会显示该文件。但基本上,任何人都可以连接这个 URL 并显示存储中的文件。

将文件上传到存储时,控制台中有以下输出:

Making request for OperationModel(name=PutObject) with params: {'url_path': '/path/to/file.jpg', 'query_string': {}, 'method': 'PUT', 'headers': {'x-amz-meta-width': '749', 'x-amz-meta-height': '562', 'x-amz-acl': 'public-read', 'Cache-Control': 'max-age=172800', 'Content-Type': 'image/jpeg', 'User-Agent': 'Botocore/1.34.83 ua/2.0 os/macos#23.4.0 md/arch#arm64 lang/python#3.11.8 md/pyimpl#CPython cfg/retry-mode#legacy', 'Content-MD5': 'something here==', 'Expect': '100-continue'}, 'body': <_io.BytesIO object at 0x10778fbf0>, 'auth_path': '/path/to/file.jpg', 'url': 'https://location.digitaloceanspaces.com/path/to/file.jpg', 'context': {'client_region': 'region', 'client_config': <botocore.config.Config object at 0x107189210>, 'has_streaming_input': True, 'auth_type': 'v4', 's3_redirect': {'redirected': False, 'bucket': 'bucket_name', 'params': {'Bucket': 'bucket_name', 'Key': 'path/to/file.jpg', 'Body': <_io.BytesIO object at 0x10778fbf0>, 'Metadata': {'width': '749', 'height': '562'}, 'ACL': 'public-read', 'CacheControl': 'max-age=172800', 'ContentType': 'image/jpeg'}}, 'input_params': {'Bucket': 'bucket_name', 'Key': 'path/to/file.jpg'}, 'signing': {'region': 'location', 'signing_name': 's3', 'disableDoubleEncoding': True}, 'endpoint_properties': {'authSchemes': [{'disableDoubleEncoding': True, 'name': 'sigv4', 'signingName': 's3', 'signingRegion': 'fra1'}]}}}
Event request-created.s3.PutObject: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x1071891d0>>
Event choose-signer.s3.PutObject: calling handler <function set_operation_specific_signer at 0x106070fe0>
Event before-sign.s3.PutObject: calling handler <function remove_arn_from_signing_path at 0x106073560>
Event before-sign.s3.PutObject: calling handler <bound method S3ExpressIdentityResolver.resolve_s3express_identity of <botocore.utils.S3ExpressIdentityResolver object at 0x1071a8c10>>
Calculating signature using v4 auth.
CanonicalRequest:
PUT
/path/to/file.jpg

cache-control:max-age=172800
content-md5:something==
content-type:image/jpeg
host:location.digitaloceanspaces.com
x-amz-acl:public-read
x-amz-content-sha256:UNSIGNED-PAYLOAD
x-amz-date:20240412T204214Z
x-amz-meta-height:562
x-amz-meta-width:749

cache-control;content-md5;content-type;host;x-amz-acl;x-amz-content-sha256;x-amz-date;x-amz-meta-height;x-amz-meta-width
UNSIGNED-PAYLOAD
StringToSign:
AWS4-HMAC-SHA256
20240412T204214Z
20240412/location/s3/aws4_request
something_here
Signature:
something_here

此输出来自

boto3
模块(我假设) - 我不确定是否可以从我的 Python 脚本访问此数据。

但是,关于访问上传文件的正确且安全的方式 - 我认为我将 URL 连接到文件的方式不是很安全。正确的做法是什么?

python amazon-web-services amazon-s3 digital-ocean digital-ocean-spaces
1个回答
0
投票

(我的回答是基于我对 Amazon S3 的了解,而不是专门针对 Digital Ocean。)

上传到 S3(以及 Digital Ocean)的任何数据在默认情况下都是私有的。也就是说,只有具有必要权限的经过身份验证的用户才能访问数据。 如果您希望

世界上的任何人

访问该对象,那么您可以使用您提到的ACL=public-read,或者您可以创建一个

存储桶策略
,使整个存储桶(或存储桶的子集)公开。这将使任何人都可以公开访问该对象(或存储桶)。 如果您只想访问

在 Digital Ocean 中定义的用户

,则需要通过经过身份验证的 API 调用(例如使用 AWS CLI 或 boto3 以及 Digital Ocean 凭证)来完成访问对象的请求。 例如,如果您想将对象下载到您自己的计算机上,则可以将 DO 凭据保存到配置文件中,然后可以使用

aws s3 cp s3://bucketname/foo.txt .

下载该对象。它会起作用,因为您拥有授予对该对象的访问权限的凭据。

或者,假设您有一个 Web 应用程序,并且您希望在网页上

显示私有图像

,或者可能提供指向私有对象的链接。由于该对象是私有的,您可以使用 Amazon S3 预签名 URL,它提供对 Amazon S3 中私有对象的限时访问。该应用程序将生成一个包含授权信息的链接,因此允许在定义的时间段内访问该对象。 (基本上,URL 有一个额外的 signature,它是一个安全哈希,授予访问私有对象的权限。)

© www.soinside.com 2019 - 2024. All rights reserved.