问题标题很宽泛,但我的问题不是。我只是想澄清一下我的方法。我有一个s3桶与封锁的公共访问。将http referer桶政策。这就是它的样子。
{
"Version": "2008-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests referred by www.mysite.com and mysite.com",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::storage/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://www.example.com/*",
"https://example.com/*",
]
}
}
}
]
}
如果我的前端(在我的ld上)试图通过URL访问s3资源,我仍然会得到一个错误。(URL示例-https://storage.s3.amazonaws.com/path/to/my/file.png
).
我放弃了直接点击s3 URL的方法,并决定在我的TLD上构建一个后端实用程序,该实用程序将获取有问题的s3资源并将其发送回前端。所以URL看起来像这样,https://<tld>/fetch-s3-resource/path/to/file.png
。
-我发现签名URL应该允许用户通过URL公开访问资源。这应该可以解决我的问题,但我仍然设置了公共访问"off"我真的不知道该切换哪个开关,以便允许带有签名url的用户能够访问资源。
下面是s3签名URL的示例。这是文档
的链接import logging
import boto3
from botocore.exceptions import ClientError
def create_presigned_url(bucket_name, object_name, expiration=3600):
"""Generate a presigned URL to share an S3 object
:param bucket_name: string
:param object_name: string
:param expiration: Time in seconds for the presigned URL to remain valid
:return: Presigned URL as string. If error, returns None.
"""
# Generate a presigned URL for the S3 object
s3_client = boto3.client('s3')
try:
response = s3_client.generate_presigned_url('get_object',
Params={'Bucket': bucket_name,
'Key': object_name},
ExpiresIn=expiration)
except ClientError as e:
logging.error(e)
return None
# The response contains the presigned URL
return response
更新更新-因为这个问题还不够清楚,而且我似乎对我的"松散"有一些自由。语言,让我澄清一些事情。
1 -我到底想做什么?我想保证s3存储桶的安全,只有用户的预设URL由"我"生成。可以访问任何资源。2 -当我问"我的方法"时;是更好还是有其他方法我是什么意思?我想知道是否有一个" native "/aws提供了一种访问桶的方式,而不必编写一个后端端点来获取资源并将其扔回前端。我如何衡量一种方法与另一种方法?我认为这一点非常明显,如果您的框架*提供了一个身份验证流,您就不必尝试从头开始编写。这个逻辑在这里也适用,如果有一种方法可以访问AWS列出的对象,那么我可能不应该去写我自己的"hack">
预签名url通过。你可以阻止所有的公共访问,仍然能够生成签名的URL和服务它的前端。我已经在我的问题中链接了官方文档,这是我最后写的一段代码。
def create_presigned_url(bucket_name, bucket_key, expiration=3600, signature_version='s3v4'):
"""Generate a presigned URL for the S3 object
:param bucket_name: string
:param bucket_key: string
:param expiration: Time in seconds for the presigned URL to remain valid
:param signature_version: string
:return: Presigned URL as string. If error, returns None.
"""
s3_client = boto3.client('s3',
aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
config=Config(signature_version=signature_version),
region_name='us-east-1'
)
try:
response = s3_client.generate_presigned_url('get_object',
Params={'Bucket': bucket_name,
'Key': bucket_key},
ExpiresIn=expiration)
except ClientError as e:
logging.error(e)
return None
# The response contains the pre-signed URL
return response