Signed URL

要通过Cloudfront分发一些会员视频时,可以使用CloudFront Signed URL, Cloudfront signed URL只能通过SDK创建。

原理

用户登录认证 -> 访问会员视频 -> SDK生成下载链接 -> 用户拿到链接访问。

这个过程中,S3是隐藏在背后的,只能通过CloudFront来访问。

img

测试

我们将在cloudfront中创建两类path:

  • 当访问/private目录时,触发认证机制,用户需要用signed URL才能访问下面的文件
  • 其他目录可以公开访问

image-20230608093107642

在CloudFront中创建两个behavior如下:

image-20230608094354980

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

image-20230608094238270

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

image-20230608094431904

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

image-20230608094505061

执行以下命令,创建一个public key和一个private key:

openssl genrsa -out cloudfront-key.pem 2048
openssl rsa -pubout -in cloudfront-key.pem -out cloudfront-key.pub

创建完成后,复制public key的内容:

image-20230608094739505

粘贴到create public key的页面:

image-20230608094812794

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

image-20230608094837871

创建key group:

image-20230608094900369

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

image-20230608094926137

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

image-20230608095025607

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

image-20230608095102693

接下来我们将实现使用代码生成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:

image-20230608100259000

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

image-20230608100207503


补充:也可以使用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