💂‍♀️

Cloudflare R2でCORS周りの設定をする

2023/01/19に公開

Workers等を通さずにWebクライアント等からR2へリクエストする場合、バケットをPublicなものにするか、CORSの設定をする必要があります。今回はバケットにCORSを設定して、クライアントから署名付きURLを通して、直接オブジェクトの追加・読み取りをできるようにします。

また、今回はREST APIから設定しますが、S3 SDKからでも同様の設定は可能です。(記事の最後にNode.jsでの実装も載せておきます。)

CORSRuleの書き方

R2のCORS Ruleは、AWS S3のCORS Ruleと同様の形式でリクエストが可能です。今回はXMLでリクエストを記述します。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedHeader>Content-Type</AllowedHeader>
        <AllowedHeader>Content-Length</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

オブジェクトの追加(PutObject)とオブジェクトの取得(GetObject)をを許可するため、今回はPUTGETメソッドを許可しています。

注意点としてR2の仕様で、AllowedHeaderに*を設定することはできないため(参照)、ヘッダに含ませたい値は事前に指定しておく必要があります。

リクエストの送信

今回はPostmanを使用してリクエストを送信します。Postmanを使う理由は、以下のようにAWS Signatureのための型が用意されており、リクエストの送信が簡単なためです。

Authorizationは以下のように設定してください。(AccessKeyとSecretKeyは適宜指定)

Bodyには先ほどのCORS Ruleを記述します

リクエスト先: https://<BUCKET-NAME>.<ACCOUNT-ID>.r2.cloudflarestorage.com/?cors

リクエストを送信し200 OKが帰ってくればリクエストは成功です。

Node.js実装

import { PutBucketCorsCommand, S3Client } from "@aws-sdk/client-s3";

const ACCESS_KEY = "YOUR_ACCESS_KEY"; //TODO: replace
const ACCOUNT_ID = "YOUR_ACCOUNT_ID"; //TODO: replace
const SECRET_KEY = "YOUR_SECRET_KEY"; //TODO: replace
const BUCKET_NAME = "YOUR_BUCKET_NAME"; //TODO: replace

const s3Client = new S3Client({
  region: "auto",
  endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: `${ACCESS_KEY}`,
    secretAccessKey: `${SECRET_KEY}`,
  },
});

async function main() {
  const response = await s3Client.send(
    new PutBucketCorsCommand({
      Bucket: BUCKET_NAME,
      CORSConfiguration: {
        CORSRules: new Array({
          AllowedHeaders: ["content-type", "content-length"], // "*"は使わない
          AllowedMethods: ["GET", "PUT"],
          AllowedOrigins: ["*"],
          ExposeHeaders: [],
        }),
      },
    })
  );
  console.dir(response);
}

main();
TheCreator

Discussion