预签名 URL 是 S3 概念 ↗,用于在不暴露 API 凭据的情况下授予对对象的临时访问。预签名 URL 在 URL 本身中包含签名参数,授权任何拥有该 URL 的人在 URL 过期前对特定对象执行特定操作(如 GetObject 或 PutObject)。
它们非常适用于授予对特定对象的临时访问,例如允许用户直接上传到 R2,或提供限时下载链接。
要生成预签名 URL,您需要指定:
- 资源标识符:账户 ID、存储桶名称和对象路径
- 操作:允许的 S3 API 操作(GET、PUT、HEAD 或 DELETE)
- 过期时间:1 秒到 7 天(604,800 秒)的超时
预签名 URL 在客户端生成,无需与 R2 通信,仅需 R2 API 凭据和 AWS Signature Version 4 签名算法的实现。
R2 支持两种限时访问模式。它们有重叠,但权衡不同:
| 模式 | 授予权限 | 适用场景 |
|---|---|---|
| 预签名 URL(本页) | 对单个对象的单个 S3 操作 | 无需 S3 客户端即可授予对单个对象的直接 HTTP 访问,例如浏览器上传或可分享的下载链接 |
| 临时凭据 | 多个 S3 操作,范围限定于存储桶和一组允许的操作,可选限定于特定路径 | 使用标准 S3 客户端或 SDK 在限定会话中执行多个操作的调用方 |
import { S3Client, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const S3 = new S3Client({
region: "auto", // Required by SDK but not used by R2
// Provide your Cloudflare account ID
endpoint: `https://<ACCOUNT_ID>.r2.cloudflarestorage.com`,
// Retrieve your S3 API credentials for your R2 bucket via API tokens (see: https://developers.cloudflare.com/r2/api/tokens)
credentials: {
accessKeyId: '<ACCESS_KEY_ID>',
secretAccessKey: '<SECRET_ACCESS_KEY>',
},
});
// Generate presigned URL for reading (GET)
const getUrl = await getSignedUrl(
S3,
new GetObjectCommand({ Bucket: "my-bucket", Key: "image.png" }),
{ expiresIn: 3600 }, // Valid for 1 hour
);
// https://my-bucket.<ACCOUNT_ID>.r2.cloudflarestorage.com/image.png?X-Amz-Algorithm=...
// Generate presigned URL for writing (PUT)
// Specify ContentType to restrict uploads to a specific file type
const putUrl = await getSignedUrl(
S3,
new PutObjectCommand({
Bucket: "my-bucket",
Key: "image.png",
ContentType: "image/png",
}),
{ expiresIn: 3600 },
);import boto3
s3 = boto3.client(
service_name="s3",
# Provide your Cloudflare account ID
endpoint_url='https://<ACCOUNT_ID>.r2.cloudflarestorage.com',
# Retrieve your S3 API credentials for your R2 bucket via API tokens (see: https://developers.cloudflare.com/r2/api/tokens)
aws_access_key_id='<ACCESS_KEY_ID>',
aws_secret_access_key='<SECRET_ACCESS_KEY>',
region_name="auto", # Required by SDK but not used by R2
)
# Generate presigned URL for reading (GET)
get_url = s3.generate_presigned_url(
'get_object',
Params={'Bucket': 'my-bucket', 'Key': 'image.png'},
ExpiresIn=3600 # Valid for 1 hour
)
# https://my-bucket.<ACCOUNT_ID>.r2.cloudflarestorage.com/image.png?X-Amz-Algorithm=...
# Generate presigned URL for writing (PUT)
# Specify ContentType to restrict uploads to a specific file type
put_url = s3.generate_presigned_url(
'put_object',
Params={
'Bucket': 'my-bucket',
'Key': 'image.png',
'ContentType': 'image/png'
},
ExpiresIn=3600
)# Generate presigned URL for reading (GET)
# The AWS CLI presign command defaults to GET operations
aws s3 presign --endpoint-url https://<ACCOUNT_ID>.r2.cloudflarestorage.com \
s3://my-bucket/image.png \
--expires-in 3600
# Output:
# https://<ACCOUNT_ID>.r2.cloudflarestorage.com/my-bucket/image.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...
# Note: The AWS CLI presign command only supports GET operations.
# For PUT operations, use one of the SDK examples above.有关完整示例和其他操作,请参阅特定 SDK 文档:
生成预签名 URL 时,可通过以下方式限制滥用和误用:
- 限制 Content-Type:在 SDK 参数中指定允许的
Content-Type。签名将包含此请求头,若客户端为上传请求发送不同的Content-Type,上传将失败并返回403/SignatureDoesNotMatch错误。 - 配置 CORS:若预签名 URL 将从浏览器使用,请在存储桶上设置 CORS 规则,控制哪些源站可以发起请求。
生成后,像使用任何 HTTP 端点一样使用预签名 URL。签名嵌入 URL 中,无需额外的身份验证请求头。
# Download using a GET presigned URL
curl "https://my-bucket.<ACCOUNT_ID>.r2.cloudflarestorage.com/image.png?X-Amz-Algorithm=..."
# Upload using a PUT presigned URL
curl -X PUT "https://my-bucket.<ACCOUNT_ID>.r2.cloudflarestorage.com/image.png?X-Amz-Algorithm=..." \
--data-binary @image.png您也可以直接在 Web 浏览器、移动应用或任何 HTTP 客户端中使用预签名 URL。同一预签名 URL 可在过期前重复使用。
以下示例是使用 R2 API 凭据并遵循 AWS Signature Version 4 签名过程创建的预签名 URL:
https://my-bucket.123456789abcdef0123456789abcdef.r2.cloudflarestorage.com/photos/cat.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=CFEXAMPLEKEY12345%2F20251201%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20251201T180512Z&X-Amz-Expires=3600&X-Amz-Signature=8c3ac40fa6c83d64b4516e0c9e5fa94c998bb79131be9ddadf90cefc5ec31033&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject在此示例中,此预签名 URL 对账户 ID 为 123456789abcdef0123456789abcdef 的 my-bucket 存储桶中的 photos/cat.png 对象执行 GetObject。组成此预签名 URL 的关键签名参数包括:
X-Amz-Algorithm:标识用于签名 URL 的算法。X-Amz-Credential:包含用于计算签名的凭据信息。X-Amz-Date:创建签名时的日期和时间(ISO 8601 格式)。X-Amz-Expires:预签名 URL 保持有效的时长(秒),从X-Amz-Date开始计算。X-Amz-Signature:证明 URL 使用密钥签名的签名。X-Amz-SignedHeaders:列出签名计算中包含的 HTTP 请求头。
R2 支持以下 HTTP 方法的预签名 URL:
GET:从存储桶获取对象HEAD:从存储桶获取对象元数据PUT:向存储桶上传对象DELETE:从存储桶删除对象
目前不支持 POST(通过 HTML 表单的分片上传)。
将预签名 URL 视为 bearer token。任何拥有 URL 的人可在过期前执行指定操作。仅与预期接收者分享预签名 URL,敏感操作请考虑使用较短的过期时间。
预签名 URL 适用于 S3 API 域名(<ACCOUNT_ID>.r2.cloudflarestorage.com),不能用于自定义域名。
若需要通过自定义域名(公开存储桶)访问 R2 存储桶并进行身份验证,请使用 WAF HMAC 验证功能(需要 Pro 计划或更高版本)。