INTEGRITY Документация

Presigned URLs

Presigned URL представляют собой Концепция S3 для предоставления временного доступа к объектам без раскрытия ваших API credentials. Presigned URL включает параметры подписи прямо в самом URL, что позволяет любому, у кого есть этот URL, выполнить определённую операцию (например, GetObject или PutObject) к определённому объекту, пока не истечёт срок действия URL.

Они отлично подходят для предоставления временного доступа к отдельным объектам, например, чтобы позволить пользователям загружать файлы напрямую в R2 или выдавать ссылки для скачивания с ограниченным сроком действия.

Чтобы создать presigned URL, укажите:

  1. Идентификатор ресурса: ID учётной записи, имя бакета и путь к объекту
  2. Операция: разрешённая операция S3 API (GET, PUT, HEAD или DELETE)
  3. Срок действия: тайм-аут от 1 секунды до 7 дней (604,800 секунд)

Presigned URL создаются на стороне сервера без обращения к R2: для этого нужны только учётные данные R2 API и реализация алгоритма подписи AWS Signature Version 4.

Выбор подхода

R2 поддерживает два подхода к ограниченному по времени доступу. Они пересекаются по функциям, но имеют разные компромиссы:

Шаблон Разрешения Подходит для
Presigned URL (эта страница) Одна операция S3 над одним объектом Предоставление прямого HTTP-доступа к отдельному объекту без S3-клиента, например для загрузки через браузер или для ссылки на скачивание
Временные учётные данные Несколько операций S3, ограниченных бакетом и набором разрешённых операций, а также, при необходимости, конкретными путями Вызывающие стороны, использующие стандартный клиент S3 или SDK для выполнения нескольких операций в рамках заданной сессии

Создание presigned URL

Предварительные требования

Примеры 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:

Рекомендации

При создании presigned URL злоупотребления и неправильное использование можно ограничить следующими способами:

Использование presigned URL

После создания presigned URL используется как обычная конечная точка HTTP. Подпись встроена прямо в 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

Вы также можете использовать presigned URL напрямую в веб-браузерах, мобильных приложениях или любом HTTP-клиенте. Один и тот же presigned URL можно использовать многократно, пока не истечёт срок его действия.

Пример presigned URL

Ниже приведён пример presigned URL, созданного с использованием учётных данных R2 API и процесса подписи AWS Signature Version 4:

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 выполняет GetObject на объекте photos/cat.png в бакете my-bucket в аккаунте с id 123456789abcdef0123456789abcdef. Ключевые параметры подписи, из которых состоит этот заранее подписанный URL, следующие:

Поддерживаемые операции

R2 поддерживает Presigned URL для следующих HTTP-методов:

POST (загрузка файлов через HTML-формы в формате multipart/form-data) в настоящее время не поддерживается.

Соображения по безопасности

Относитесь к presigned URL как к bearer-токенам. Пока срок действия URL не истек, любой, у кого он есть, может выполнить указанную операцию. Передавайте presigned URL только тем, кому они предназначены, и рассмотрите возможность использования короткого срока действия для операций с конфиденциальными данными.

Пользовательские домены

Presigned URL работают с доменом S3 API (<ACCOUNT_ID>.r2.cloudflarestorage.com) и не может использоваться с пользовательскими доменами.

Если вам нужна аутентификация для бакетов R2, доступных через пользовательские домены (публичных бакетов), используйте Функция проверки HMAC в WAF (требуется план Pro или выше).

R2 API-токены

Создайте учётные данные для генерации presigned URL.

Публичные бакеты

Альтернативный способ обеспечить публичный доступ на чтение без аутентификации.

Привязки R2 в Workers

Альтернатива для доступа к R2 на стороне сервера со встроенной аутентификацией.

Хранение пользовательского контента

Руководство по архитектуре обработки пользовательских загрузок с помощью R2.