Closed8

Cloudflare R2 > API > Workers API > Use R2 from Workers

kwnkwn
  • Cloudflareのアカウントは作成済み
  • R2のSubscriptionは有効化済み
  • npm v9.4.2
  • Node.js v18.14.0
  • create-cloudflare v2.1.1
  • wrangler v3.5.1

create-cloudflareとwranglerはコマンド実行時にインストールできるので事前のインストール不要

kwnkwn

1. Create a new application with C3

C3(create-cloudflare-cli)を使ってプロジェクトを作成する。

npm create cloudflare@latest


ここから先はドキュメントに書いてない。
どのディレクトリにアプリを作るか聞かれる。
「use-r2-from-workers」と入力。

In which directory do you want to create your application?
dir ./use-r2-from-workers


どのような種類のアプリケーションを作りたいか聞かれる。
「"Hello World" Worker」を選択。

What type of application do you want to create?
● "Hello World" Worker


TypeScriptを使うか聞かれる。
「No」を選択。

Do you want to use TypeScript?
Yes / No


Gitを使うか聞かれる。
「No」を選択。

Do you want to use git for version control?
Yes / No


デプロイするか聞かれる。
「No」を選択。

Do you want to deploy your application?
Yes / No
kwnkwn

3. Bind your bucket to a Worker

wrangler.tomlに以下を追加する。
上がダブルクォーテーション、[[r2_buckets]]の方がシングルクォーテーションで文字列を囲っているのは何故かわからない。意味がないなら気持ち悪いので統一したいがとりあえずそのまま進める。

wrangler.toml
account_id = "YOUR_ACCOUNT_ID"
workers_dev = true

[[r2_buckets]]
binding = 'MY_BUCKET'
bucket_name = 'sample1'


YOUR_ACCOUNT_IDと書いているアカウントIDは以下のコマンドで表示できる。
ダッシュボードのR2からも確認できる。

npx wrangler whoami
┌────────────────────────────────┬──────────────────────────────────┐
│ Account Name                   │ Account ID                       │
├────────────────────────────────┼──────────────────────────────────┤
│ xxx@xxx.com's Account          │ YOUR_ACCOUNT_ID                  │
└────────────────────────────────┴──────────────────────────────────┘
kwnkwn

4. Access your R2 bucket from your Worker

オブジェクト(=ファイルのことだと思っている)の取得、書き込み、削除を行う処理を書く。
ドキュメントでは「index.js」に処理を書いているが、プロジェクト作成時に「worker.js」ができているのでこれを使う。

worker.js
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const key = url.pathname.slice(1);

    switch (request.method) {
      case 'PUT':
        await env.MY_BUCKET.put(key, request.body);
        return new Response(`Put ${key} successfully!`);
      case 'GET':
        const object = await env.MY_BUCKET.get(key);

        if (object === null) {
          return new Response('Object Not Found', { status: 404 });
        }

        const headers = new Headers();
        object.writeHttpMetadata(headers);
        headers.set('etag', object.httpEtag);

        return new Response(object.body, {
          headers,
        });
      case 'DELETE':
        await env.MY_BUCKET.delete(key);
        return new Response('Deleted!');

      default:
        return new Response('Method Not Allowed', {
          status: 405,
          headers: {
            Allow: 'PUT, GET, DELETE',
          },
        });
    }
  },
};
kwnkwn

5. Bucket access and privacy

アクセス制限を作る。
ヘッダーのX-Custom-Auth-Keyを確認しAUTH_KEY_SECRETと一致すれば許可する。

まずはシークレット変数を作る。正式な用語の名称がわからないが、コマンドの説明

Manage the secret variables for a Worker.

と書いてあるのでとりあえずシークレット変数と呼ぶ。
プロジェクトのディレクトリに移動して以下のコマンドを実行する。
値の入力を求められるので「sample1-sercret」とする。

npx wrangler secret put AUTH_KEY_SECRET
✔ Enter a secret value: … ***************
🌀 Creating the secret for the Worker "use-r2-from-workers" 
✨ Success! Uploaded secret AUTH_KEY_SECRET


シークレット変数は環境変数をwrangler.tomlに書かずに運用するための方法っぽい。
以下の記事が参考になった。
https://zenn.dev/mr_ozin/articles/645502f4a621d6

コードに戻り、ヘッダーを確認する処理を追加する。

worker.js
const ALLOW_LIST = ['cat-pic.jpg'];

// Check requests for a pre-shared secret
const hasValidHeader = (request, env) => {
  return request.headers.get('X-Custom-Auth-Key') === env.AUTH_KEY_SECRET;
};

function authorizeRequest(request, env, key) {
  switch (request.method) {
    case 'PUT':
    case 'DELETE':
      return hasValidHeader(request, env);
    case 'GET':
      return ALLOW_LIST.includes(key);
    default:
      return false;
  }
}

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const key = url.pathname.slice(1);

    if (!authorizeRequest(request, env, key)) {
      return new Response('Forbidden', { status: 403 });
    }

    // ...
  }
};
kwnkwn

6. Deploy your bucket

Workerをデプロイする。

npx wrangler deploy


以下はデプロイされたWorkerを試すためのコマンド。
your-workerの部分は自分のプロジェクトに合わせる必要あり。

curl https://your-worker.dev/cat-pic.jpg -X PUT --data-binary 'test'

=> ヘッダーがないので「Forbidden」と出力される。

curl https://your-worker.dev/cat-pic.jpg -X PUT --header "X-Custom-Auth-Key: hotdog" --data-binary 'test'

=> X-Custom-Auth-KeyとAUTH_KEY_SECRETが一致しないので「Forbidden」と出力される。

curl https://your-worker.dev/cat-pic.jpg -X PUT --header "X-Custom-Auth-Key: sample1-sercret" --data-binary 'test'

=> 書き込みに成功するので「Put cat-pic.jpg successfully!」と出力される。

curl https://your-worker.dev/foo

=> 許可してないオブジェクト「foo」を取得しようとしているので「Forbidden」と出力される。

curl https://your-worker.dev/cat-pic.jpg

=> 取得に成功するので「test」と出力される。

このスクラップは2023/08/22にクローズされました