strapiで画像をCloud flareのR2に保存させる方法

## 前提
・strapiはすでに構築済み、画像のアップロードやコンテンツ作成が可能な状態

## strapi-provider-cloudflare-r2をインストール

```terminal
# using yarn
yarn add strapi-provider-cloudflare-r2

# using npm
npm install strapi-provider-cloudflare-r2 --save

# using pnpm
pnpm add strapi-provider-cloudflare-r2
```

## strapiのプラグイン設定ファイルを編集します
```typescript:./config/plugin.ts
module.exports = ({ env }) => ({
  upload: {
    config: {
      provider: "strapi-provider-cloudflare-r2",
      providerOptions: {
        accessKeyId: env("CF_ACCESS_KEY_ID"),
        secretAccessKey: env("CF_ACCESS_SECRET"),
        /**
         * `https://<ACCOUNT_ID>.r2.cloudflarestorage.com`
         */
        endpoint: env("CF_ENDPOINT"),
        params: {
          Bucket: env("CF_BUCKET"),
        },
        /**
         * Set this Option to store the CDN URL of your files and not the R2 endpoint URL in your DB.
         * Can be used in Cloudflare R2 with Domain-Access or Public URL: https://pub-<YOUR_PULIC_BUCKET_ID>.r2.dev
         * This option is required to upload files larger than 5MB, and is highly recommended to be set.
         * Check the cloudflare docs for the setup: https://developers.cloudflare.com/r2/data-access/public-buckets/#enable-public-access-for-your-bucket
         */
        cloudflarePublicAccessUrl: env("CF_PUBLIC_ACCESS_URL"),
        /**
         * Sets if all assets should be uploaded in the root dir regardless the strapi folder.
         * It is useful because strapi sets folder names with numbers, not by user's input folder name
         * By default it is false
         */
        pool: false,
      },
      actionOptions: {
        upload: {},
        uploadStream: {},
        delete: {},
      },
    },
  },
});

```

## 環境変数を使用しているので、envファイルを編集
```text:./.env
// 初期設定色々
CF_ACCESS_KEY_ID=
CF_ACCESS_SECRET=
CF_ENDPOINT=
CF_BUCKET=
CF_PUBLIC_ACCESS_URL=
```

## 各キーをClouf flareから取得
・CF_ACCESS_KEY_ID
・CF_ACCESS_SECRET
・CF_ENDPOINT
###  CF_ACCESS_KEY_ID、CF_ACCESS_SECRET、CF_ENDPOINTの取得
cloud flareのAPIトークンを発行して、それぞれの項目を取得します
 1. R2概要ページ 右側"R2 API トークンの管理"から移動
 2. APIトークンページにてAPI トークン作成ボタンをクリック
 3. 権限がデフォルトの状態だと読み取りのみなので、strapiから更新できるように書き込み可能な権限に変更
 4. 作成後、表示されるトークンの値、アクセスキーID、シークレットアクセスキー、エンドポイントをそれぞれ保存
 
 

### CF_PUBLIC_ACCESS_URLの取得
作成したR2バケットの詳細ページに以降し、下記を行います
1. 設定タブに移動
1. r2.devサブドメインのアクセスを許可に変更します
1. 表示されたパブリックr2.devバケットURLが該当のURLになります。

### CF_BUCKETの取得
設定したバケット名になります

## strapiのセキュリティミドルウェアを変更
デフォルトの状態だではメディアライブラリでサムネイル表示ができない為、設定を書き換えます。

```typescript:./config/middlewares.ts
module.exports = ({ env }) => [
  'strapi::logger',
  'strapi::errors',
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::query',
  'strapi::body',
  'strapi::session',
  'strapi::favicon',
  'strapi::public',
  {
    name: "strapi::security",
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          "connect-src": ["'self'", "https:"],
          "img-src": [
            "'self'",
            "data:",
            "blob:",
            "market-assets.strapi.io",
            env("CF_PUBLIC_ACCESS_URL") ? env("CF_PUBLIC_ACCESS_URL").replace(/^https?:\/\//, "") : "",
          ],
          "media-src": [
            "'self'",
            "data:",
            "blob:",
            "market-assets.strapi.io",
            env("CF_PUBLIC_ACCESS_URL") ? env("CF_PUBLIC_ACCESS_URL").replace(/^https?:\/\//, "") : "",
          ],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
];
```

### バケットのCORS設定
R2エンドポイントのCORS設定を行います
バケット詳細ページの設定タブ中央部にあるCORSポリシーから編集できます。
```json:CORSポリシーを編集する
[
  {
    "AllowedOrigins": ["*"],
    "AllowedMethods": ["GET"]
  }
]
```
上記は全て許可する状態です。特定のIPに設定したい場合は"*"を許可するURLに設定してください。

### strapiを再起動して完了
再起動後はstrapiからメディアをアップロードを行い、無事にR2に入っているか確認してください。
お疲れ様でした！

参考URL

https://market.strapi.io/providers/strapi-provider-cloudflare-r2