2026年9月30日 · 阅读约 5 分钟

如何用预签名 URL 分享私有 S3 和 R2 文件

并不是所有文件都该放在公开存储桶里。合同、发票或尚未发布的构建可以保持私有,同时仍然能通过只在限定时间内有效的链接分享出去。

预签名 URL 的原理

URL 中包含 S3 校验请求所需的全部信息:签名所用的密钥、签名时间、有效时长以及签名本身。它看起来像这样:

https://your-bucket.s3.eu-central-1.amazonaws.com/contract.pdf
  ?X-Amz-Algorithm=AWS4-HMAC-SHA256
  &X-Amz-Credential=AKIA…/20260930/eu-central-1/s3/aws4_request
  &X-Amz-Date=20260930T120000Z
  &X-Amz-Expires=3600
  &X-Amz-SignedHeaders=host
  &X-Amz-Signature=…

签名在你的电脑上完成。在有人打开链接之前,不会向服务商发送任何内容;改动链接的任何部分都会使签名失效。

用 AWS CLI 生成

aws s3 presign s3://your-bucket/contract.pdf --expires-in 86400

这个链接的有效期为 24 小时。对于 Cloudflare R2 或其他 S3 兼容服务,把 CLI 指向对应的端点即可:

aws s3 presign s3://your-bucket/contract.pdf --expires-in 86400 \
  --endpoint-url https://<ACCOUNT_ID>.r2.cloudflarestorage.com

需要了解的限制

  • 最长 7 天。Signature Version 4 最多允许 604,800 秒,S3 和 R2 都是如此。
  • 临时凭证会更早失效。用 STS 或 SSO 会话签名的 URL,会在该会话过期时失效,即使你设置了更长的有效期。
  • R2 需要使用 API 域名。R2 的预签名 URL 只能用于 <ACCOUNT_ID>.r2.cloudflarestorage.com,不能用于自定义域名。
  • 任何拿到链接的人都能使用。在过期之前,请像对待密码一样对待它。
  • 无法单独撤销某个链接。要提前让链接失效,请删除或重命名对象,或停用签名所用的访问密钥。

预签名 URL 还是公开存储桶?

本来就要给人看、并且应该长期有效的文件,例如文档里的截图、README 中的图片,请使用公开存储桶。敏感或短期的内容请使用预签名 URL。很多人会各准备一个存储桶,按文件选择。

常见问题

预签名 URL 的有效期能超过 7 天吗?

S3 和 R2 使用的 Signature Version 4 做不到。如果需要更长时间的访问,请公开该文件,或在旧链接过期后生成新链接。

为什么我的预签名 URL 返回 SignatureDoesNotMatch?

通常是 URL 在签名后被改动过,例如被邮件客户端修改,或者把主机换成了自定义域名。区域和端点设置也必须与存储桶一致。

Backblaze B2 和 MinIO 支持预签名 URL 吗?

支持。两者都通过 S3 兼容 API 支持 Signature Version 4 预签名 URL。