python - 来自 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_signature
和canonical_string
功能。sign_string
_inject_signature
以前有没有人解决过这个问题?我在正确的轨道上吗?
我正在使用 python 3、django 2 和 postgresql 10。
编辑:我可以考虑使用此处讨论的 cursor_factory 参数制作自己的光标。http://initd.org/psycopg/docs/extras.html#connection-and-cursor-subclasses
也许找到一种方法来传递函数映射,以便任何需要特别注意的列都可以在原点得到它,而不是再次循环结果集。走着瞧。
解决方案
这里有一些 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 中的用户定义函数。
推荐阅读
- postgresql - 根据 postgres 中的字段从两个表中获取唯一数据
- python - 如何在 Python 中从 pandas 数据帧生成分层 JSON 树
- java - 有没有办法在 Java 中获取另一个正在运行的应用程序的输出
- node.js - 为什么我在本机反应中总是收到“网络请求失败”错误?
- java - 在 Leetcode 中计数 Nice Pairs 给了我错误的结果
- python - 使用 utf8mb4 字符集的 mysql.connector 中的 executemany 方法不起作用(python)
- java - 如何在java中检查电子邮件地址
- encoding - 任何缩短字符串的编码解码方法
- python - 从 .csv 文件中读取每个字符串
- java - 我可以将这两者合二为一吗?