署名付き URL(presigned URL)は、S3 の考え方 ↗ で、API 認証情報を公開せずにオブジェクトへの一時アクセスを許可します。署名付き 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 は期限付きアクセス向けに 2 つのパターンをサポートします。重なる部分はありますが、トレードオフが異なります。
| パターン | 許可する内容 | 向いている用途 |
|---|---|---|
| 署名付き URL(このページ) | 1 つのオブジェクトに対する 1 つの S3 操作 | ブラウザからのアップロードや共有可能なダウンロードリンクなど、S3 クライアントなしで 1 つのオブジェクトへ直接 HTTP アクセスを渡す場合 |
| 一時認証情報 | 複数の S3 操作。バケットと許可する操作の集合、必要に応じて特定パスにスコープできる | 標準の S3 クライアントや SDK を使い、スコープしたセッション内で複数操作を行う呼び出し元 |
- アカウント ID(S3 エンドポイント URL の組み立てに使います)
- R2 API トークン(Access Key ID と Secret Access Key)
- AWS SDK または互換の S3 クライアントライブラリ
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 ルール を設定し、リクエストを送れるオリジンを制御します。
生成した署名付き 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.pngWeb ブラウザ、モバイルアプリ、任意の 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この例では、アカウント ID が 123456789abcdef0123456789abcdef のバケット my-bucket 内のオブジェクト photos/cat.png に対して GetObject を行います。この署名付き URL を構成する主な署名パラメータは次のとおりです。
X-Amz-Algorithm: URL の署名に使ったアルゴリズムを示します。X-Amz-Credential: 署名の計算に使った認証情報の情報を含みます。X-Amz-Date: 署名を作成した日時(ISO 8601 形式)です。X-Amz-Expires:X-Amz-Dateから数えた、署名付き URL が有効な秒数です。X-Amz-Signature: シークレットキーで URL が署名されたことを証明する署名です。X-Amz-SignedHeaders: 署名の計算に含めた HTTP ヘッダーの一覧です。
R2 は、次の HTTP メソッドの署名付き URL をサポートします。
GET: バケットからオブジェクトを取得しますHEAD: バケットからオブジェクトのメタデータを取得しますPUT: バケットへオブジェクトをアップロードしますDELETE: バケットからオブジェクトを削除します
POST(HTML フォーム経由のマルチパートフォームアップロード)は、現時点ではサポートしていません。
署名付き URL はベアラートークンとして扱ってください。URL を持つ人は、期限が切れるまで指定した操作を実行できます。署名付き URL は想定した相手にだけ共有し、機密性の高い操作では短い有効期限を検討してください。
署名付き URL は S3 API ドメイン(<ACCOUNT_ID>.r2.cloudflarestorage.com)で動作し、カスタムドメインでは使えません。
カスタムドメイン経由(公開バケット)で R2 バケットに認証を付けたい場合は、WAF HMAC 検証 を使います(Pro プラン以上が必要です)。