要通过Cloudfront分发一些会员视频时,可以使用CloudFront Signed URL, Cloudfront signed URL只能通过SDK创建。
用户登录认证 -> 访问会员视频 -> SDK生成下载链接 -> 用户拿到链接访问。
这个过程中,S3是隐藏在背后的,只能通过CloudFront来访问。

我们将在cloudfront中创建两类path:
/private目录时,触发认证机制,用户需要用signed URL才能访问下面的文件
在CloudFront中创建两个behavior如下:

/private/*配置保持默认,所以此时用户可以访问到下面的文件:

接下来我们将编辑这个Behavior,在Restrict viewer access部分,选择Yes:

此时需要选择Key group,所以要提前创建好。打开新的cloudfront页面,进入创建Key的页面:

执行以下命令,创建一个public key和一个private key:
openssl genrsa -out cloudfront-key.pem 2048
openssl rsa -pubout -in cloudfront-key.pem -out cloudfront-key.pub
创建完成后,复制public key的内容:

粘贴到create public key的页面:

点击创建。完成后复制这个Key的ID,后面在代码中会用到:

创建key group:

在public key部分,选择上面创建的key名称,最后点击Create key group:

回到上一个编辑Behavior的页面,刷新,选择上面创建的keygroup1。保存编辑

此时访问之前的页面(最好切成无痕模式),已不能访问:

接下来我们将实现使用代码生成signed URL,并访问这个图片。
先安装依赖:
pip3 install boto
创建cloudfront.py,代码内容如下
from boto.cloudfront.distribution import Distribution
from boto.cloudfront import CloudFrontConnection
from botocore.signers import CloudFrontSigner
import datetime
import rsa
url = "https://d26ba1pfnwuil6.cloudfront.net/private/images.jpg" # 要访问的图片URL
expire_date = datetime.datetime(2024, 6, 2) # 图片要过期的时间
key_id = 'K1NVTYJRGNST6I' # 之前创建的public key ID
def rsa_signer(message):
private_key = open('cloudfront-key.pem', 'r').read()
return rsa.sign(message, rsa.PrivateKey.load_pkcs1(private_key.encode('utf8')),'SHA-1')
cf_signer = CloudFrontSigner(key_id, rsa_signer)
signed_url = cf_signer.generate_presigned_url(url, date_less_than=expire_date)
print(signed_url)
运行python文件,生成了签名后的URL:

拿这个URL访问,可以访问到文件内容:

补充:也可以使用CLI生成Signed URL:
aws cloudfront sign --url url --key-pair-id key-id --private-key file://pem-file-path --date-less-than 2024-03-06
aws cloudfront sign --url https://d26ba1pfnwuil6.cloudfront.net/private/images.jpg --key-pair-id K1NVTYJRGNST6I --private-key cloudfront-key.pem --date-less-than 2024-03-06