【re:Invent 2024 発表】Storage Browser for Amazon S3 を React アプリに組み込みました

本記事は、Japan AWS Ambassador Advent Calendar 2024 の 2024/12/9 付記事です。

こんにちは、広野です。

2024年の re:Invent で、アプリから Amazon S3 バケットのオブジェクトを操作できるようにするための UI モジュールがリリースされました。

今回は実際に既存アプリに組み込んでみたので、その方法を紹介します。

そもそも何が嬉しいのか

  • 開発したアプリから、S3 のオブジェクトをマネジメントコンソールの UI 風に操作できる。例えば RAG アプリに必要な独自ドキュメントを S3 に格納している場合、アプリの管理画面に S3 操作用 UI を組み込み、メンテすることができるようになる。このニーズはかなりあったはず!これまでは手作りしていた方が多かったのでは?
  • UI だけでなく、アップロード、削除、変更、フォルダ作成などの機能がモジュールに組み込まれている。アクセス権限制御もそこそこいける。すなわち、開発者がそういったベーシックな機能を開発しなくて済む。超絶楽!
  • AWS 純正モジュールなので、AWS がサポートしてくれる。安心!

このアップデートは神すぎます。もともと、9月にアルファリリースされていて早期の GA を期待していたのですが、re:Invent に間に合わせてくれて嬉しいです。AWS Amplify がリリースされたのと同じぐらいの衝撃を今受けております。

実際につくってみたもの

UI はデフォルトのままにしました。カスタマイズも若干できそうです。

  • Home デフォルトで表示されます。カスタマイズ可能です。
  • 指定したバケットおよびフォルダの一覧が表示されます。ここに表示されたフォルダ配下のオブジェクトをメンテナンスできます。
  • 権限は Read / Write / Delete が選択できそうです。
  • Amazon Cognito でアプリにログインしたユーザにのみ、権限を与えています。

フォルダ名を押すと、その詳細が表示されます。ここでは bot1 を選択します。

今時点、オブジェクトがないので No Files と表示されます。

3点リーダーボタンを押すと、操作可能なメニューがハイライトされます。ここでは Upload をします。

右上の Add files ボタンを押すとファイル選択ウィンドウが表示されますが、ダイレクトに枠内に複数のアップロード対象ファイルをドラッグアンドドロップすることも可能です。最後に右下の Upload ボタンを押します。

アップロードが完了すると、Completed のステータスに変わります。今回は省略しますが、転送の進捗がパーセント表示されます。AWS マネジメントコンソールでも、S3 バケットを確認したらきちんとファイルが入っていました。

削除もしてみます。オブジェクトを選択して、Delete を選択します。

削除対象オブジェクトがリストアップされます。

右下の Delete ボタンを押すと、削除されました。省略しますが、マネジメントコンソールの方でも削除されたことを確認できました。

アーキテクチャ

今回、既存のアプリに追加で組み込んでみました。

AWS のアーキテクチャは以下のブログ記事で紹介したものと全く同じですので、こちらをご覧ください。

簡単に説明しますと。

  • Amazon Cognito ユーザープールでアプリの認証をする。
  • その際に Amazon Cognito ID プールで、認証済みユーザーに任意の Amazon S3 バケットへのアクセス権限を付与する。
  • アプリから Storage Browser でファイルを Amazon S3 と送受信する。

AWS リソースの設定

上記アーキテクチャが実現できている前提で、以下の作業が必要です。

  1. 対象の Amazon S3 バケットに CORS 設定をする。Storage Browser が REST API で S3 にアクセスするため。
  2. Amazon Cognito ID プールで Cognito ログイン済みユーザーに割り当てる IAM ロール (認証されたロール) に、対象の Amazon S3 バケットへのアクセス権限を定義する。

Amazon S3 バケットへの CORS 設定

以下の AWS 公式ドキュメントに書いてある通りです。Allowed Origins に、アクセス元アプリの URL を追加するとよりセキュアです。

Amazon Cognito ID プールの認証されたロールの設定

これです。Amazon Cognito ID プールの設定の中に、認証されたロールという設定があります。

ここに、該当の Amazon S3 バケットへの権限を設定します。

AWS が標準として紹介しているのが、Cognito ユーザー単位で権限を制御できるようにしている方法です。

私はそこまでこだわる理由がなかったので、バケット単位で権限を付与しました。

React アプリのコード

React 18.3.1 と Vite を使用している前提です。(Next.js と AWS Amplify は使用していません)

おそらく今時点では React 19 はモジュールの Dependency エラーが出るのでお勧めできません。

モジュールは、公式ドキュメント通り以下をインストールしておきます。

npm install --save @aws-amplify/ui-react-storage aws-amplify

App.jsx

Vite を使用するとソースコードのルートが main.jsx になると思うのですが、私は create-react-app の名残で App.jsx に Amplify.configure を記述していました。AWS ドキュメントには、Amplify.configure はルートに書けとありましたが直すのが面倒なのでそのままにしています。

以下の例のように、Amplify.configure を記述する必要があります。Amplify で環境をデプロイしていないので、設定はマニュアル作成です。※具体的な値は VITE_ から始まる環境変数をビルド時に持ってきます。

import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react';
import { Amplify } from 'aws-amplify';
import Loggedin from './Loggedin.jsx';
import Notloggedin from './Notloggedin.jsx';

//Cognito, S3, AppSync 連携設定
Amplify.configure({
  Auth: {
    Cognito: {
      userPoolId: import.meta.env.VITE_USERPOOLID,
      userPoolClientId: import.meta.env.VITE_USERPOOLWEBCLIENTID,
      identityPoolId: import.meta.env.VITE_IDPOOLID
    }
  },
  Storage: {
    S3: {
      bucket: import.meta.env.VITE_S3BUCKETNAMEAMPLIFYSTG,
      region: import.meta.env.VITE_REGION,
      buckets: {
        amplifystorage: {
          bucketName: import.meta.env.VITE_S3BUCKETNAMEAMPLIFYSTG,
          region: import.meta.env.VITE_REGION
        },
        kbdatasource: {
          bucketName: import.meta.env.VITE_S3BUCKETNAMEKBDATASRC,
          region: import.meta.env.VITE_REGION,
          paths: {
            "bot1/*": {
              authenticated: ["write", "get", "list", "delete"]
            },
            "bot2/*": {
              authenticated: ["write", "get", "list", "delete"]
            }
          }
        }
      }
    }
  },
  API: {
    GraphQL: {
      endpoint: import.meta.env.VITE_APPSYNC,
      region: import.meta.env.VITE_REGION,
      defaultAuthMode: 'userPool'
    }
  }
});

//ログインチェック
function Authcheck() {
  const { authStatus } = useAuthenticator((context) => [context.authStatus]);
  return (authStatus === "authenticated") ? <Loggedin /> : <Notloggedin />;
}

export default function App() {
  return (
    <Authenticator.Provider>
      <Authcheck />
    </Authenticator.Provider>
  );
}

少し解説します。

ベースは、以下の公式ドキュメントの通りなのですが、それだけでは動きませんでした。

対象の S3 バケット内のパス (フォルダ) を、指定する必要があります。仕様として、そのフォルダより上位のオブジェクトにはアクセスできません。また、そのフォルダ内のオブジェクトにどの操作を許可するかの定義をします。

以下の paths: の部分です。※これが、ドキュメントには載っていない

kbdatasource: {
  bucketName: import.meta.env.VITE_S3BUCKETNAMEKBDATASRC,
  region: import.meta.env.VITE_REGION,
  paths: {
    "bot1/*": {
      authenticated: ["write", "get", "list", "delete"]
    },
    "bot2/*": {
      authenticated: ["write", "get", "list", "delete"]
    }
  }
}

kbdatasource というのは適当に付けた名前なので、ここは任意の名称で問題なさそうです。他の設定と紐づいてはいません。

設定すれば複数 S3 バケットも操作できると思います。少なくとも paths が設定されているバケット、フォルダでないと操作ができなそうです。

Storage Browser の実装

これは公式ドキュメント通りでした。

デフォルトの UI 設定であれば、以下だけで実装できます。私の場合は Amplify でリソースをデプロイしていないので、Storage Browser を実装したい画面のコードに以下を追加しました。

import "@aws-amplify/ui-react-storage/styles.css";
import { createAmplifyAuthAdapter, createStorageBrowser } from '@aws-amplify/ui-react-storage/browser';

//中略

//Storage Browser
const { StorageBrowser } = createStorageBrowser({
  config: createAmplifyAuthAdapter()
});

//中略

//returnの中で、画面内、表示させたい箇所にこれを差し込む
{/* S3 Storage Browser */}
<StorageBrowser />

CSSはインポートしておかないと、UI デザインが崩れると思います。

コードはほんの数行なのに、S3 バケット内を操作できる UI が実装できるって、凄すぎませんか!?

まとめ

いかがでしたでしょうか。

既存 Amazon S3 バケットに Storage Browser からアクセスする方法は公式ドキュメントには載っていない情報だったのと、GA 直後で情報が少なかったのもあって、調べるのに苦労しました。ちゃんとは言い忘れましたが、AWS Amplify は一切使わず、Amazon CloudFront、Amazon S3 のホスティング環境に AWS CodePipeline 等でビルド、デプロイしています。そんな環境でも Amplify ブランドの UI モジュールは使えますので、ご安心ください。

本記事が皆様のお役に立てれば幸いです。

著者について
広野 祐司

AWS サーバーレスアーキテクチャを駆使して社内クラウド人材育成アプリとコンテンツづくりに勤しんでいます。React で SPA を書き始めたら快適すぎて、他の言語には戻れなくなりました。サーバーレス & React 仲間を増やしたいです。AWSは好きですが、それよりもフロントエンド開発の方が好きでして、バックエンド構築を簡単にしてくれたAWSには感謝の気持ちの方が強いです。
取得資格:AWS 認定は13資格、ITサービスマネージャ、ITIL v3 Expert 等
2020 - 2024 Japan AWS Top Engineer 受賞
2022 - 2024 AWS Ambassador 受賞
2023 当社初代フルスタックエンジニア認定
好きなAWSサービス:AWS Amplify / AWS AppSync / Amazon Cognito / AWS Step Functions / AWS CloudFormation

広野 祐司をフォローする

クラウドに強いによるエンジニアブログです。

SCSKクラウドサービス(AWS)は、企業価値の向上につながるAWS 導入を全面支援するオールインワンサービスです。AWS最上位パートナーとして、多種多様な業界のシステム構築実績を持つSCSKが、お客様のDX推進を強力にサポートします。

AWSアプリケーション開発クラウドソリューション
シェアする
タイトルとURLをコピーしました