首页 > 解决方案 > 来自 SQL 的 AWS 签名 URL

问题描述

我在没有公共读取访问权限的 S3 存储桶中有很多静态内容。我想通过生成签名的 url 来提供对此内容的访问。

对于大多数用例,我使用 python 和 boto3 库。我有一些原始的 SQL 查询,尽管它们直接从数据库中提取 URL 并将它们直接转储到浏览器。我宁愿不必遍历服务器上的所有结果,使用 python 将 url 转换为签名 url,然后将其发送到浏览器。我希望有一个相当于这种魔法的 SQL。

代替

select imageFileUrl from photos;

我希望能够做类似的事情

select signed_url(imageFileUrl) from photos;

为此的python boto类/函数似乎是botocore.signers.RequestSigner.sign()

经过深入研究,它的真正本质(至少对于我的用例而言)似乎是botocore.auth.HmacV1QueryAuth它的,get_signaturecanonical_string功能。sign_string_inject_signature

以前有没有人解决过这个问题?我在正确的轨道上吗?

我正在使用 python 3、django 2 和 postgresql 10。

编辑:我可以考虑使用此处讨论的 cursor_factory 参数制作自己的光标。http://initd.org/psycopg/docs/extras.html#connection-and-cursor-subclasses

也许找到一种方法来传递函数映射,以便任何需要特别注意的列都可以在原点得到它,而不是再次循环结果集。走着瞧。

标签: pythonsqldjangoamazon-s3boto3

解决方案


这里有一些 Python 可以使用 Python 2.7(这是 Redshift 使用的版本)生成预签名 URL:

import base64
import hmac
import sha
import urllib
import time

SECRET_KEY = 'abc123'
OBJECT = '/my-bucket/foo'
DURATION = 120

# Expiry time
expiry_epoch = int(time.time() + DURATION)

# Generate signature
h = hmac.new(SECRET_KEY, "GET\n\n\n" + str(expiry_epoch) + "\n" + OBJECT, sha)
signature = urllib.quote_plus(base64.encodestring(h.digest()).strip())

# Put this after the URL
print("?AWSAccessKeyId=AKIAxxx&Expires=" + str(expiry_epoch) + "&Signature=" + signature)

它将输出附加到 URL 的参数,以允许通过预签名的 URL 进行访问。

您需要将您的密钥放入代码中。

希望您随后可以将此代码转换为 Redshift 中的用户定义函数。


推荐阅读