本記事は、KDDIアジャイル開発センター(KAG)Advent Calender 2024 17 日目の記事です。
はじめに
先日リリースされた S3 の新機能 Storage Browser for Amazon S3を試してみました。これは、独自のアプリから直接 S3 データにアクセスできる機能で、Amplify UI の React コンポーネントとして提供されています。コンポーネントのドキュメントやブログを参考に構築方法を確認し、今回はこれを Remix アプリに組み込んでみます。
本記事では以下のような設定で構築していきます。
- フロントエンドは Remix(SPA Mode) を利用
- 認証処理は Amplify auth を利用
- ブラウズ対象のバケットは Amplify Storage で新規作成
環境構築
環境構築を新規で作成します。作成したソース一式は、以下に配置しましたので、必要に応じて確認してください。
実行環境
Remix: 2.15.0
aws-amplify/ui-react: 6.7.1
Node.js: 20.15.0
npm: 10.8.2
Remix(SPA Mode)
Remix を SPA Mode のテンプレートを使って、プロジェクトを作成します。
npx create-remix@latest --template remix-run/remix/templates/spa
Amplify Gen 2 をセットアップ
npm create amplify@latest
Amplify UI React, Storage
npm install @aws-amplify/ui-react aws-amplify @aws-amplify/ui-react-storage
起動してみる
以下のコマンドを実行して、localhost:5173 で起動していれば OK
npm run dev
Amplify で必要なリソースを作成
Storage Browser を利用するために必要なリソースを作成していきます。Authentication としては、Amplify auth, AWS IAM Identity Center and S3 Access Grants, Customer managed auth から選択することができます。今回は素早く立ち上げることができそうなので、 Amplify auth (認証は Cognito) を使って構築していきます。
また、ブラウズ対象の S3 バケットは、Amplify Storage を利用して、S3 バケットの作成、アクセスするための設定を実施します。
既存の S3 バケットを利用する場合は、CORS を有効にする必要があります。
詳細は公式ドキュメントを確認してください。
Authentiction
公式ドキュメントにある通り、リソースを設定します。利用環境や制約に応じて設定を変更することができます。
import { defineAuth } from "@aws-amplify/backend";
export const auth = defineAuth({
loginWith: {
email: true,
},
});
バックエンドのリソースに作成した、auth
を追加します。
import { defineBackend } from "@aws-amplify/backend";
import { auth } from "./auth/resource";
defineBackend({
auth,
});
Storage
今回は Amplify で新規で S3 バケットを作成します。バケットの設定はこちらのドキュメントを参考に作成します。ここでバケット内のオブジェクトのプリフィックスやキーに応じてアクセス制御の設定を定義します。
今回作成するバケットには以下のようなアクセス制御を入れました。
-
public/*
- 匿名ユーザー(未認証ユーザー)に読み取り権限を付与
- 認証ユーザー(誰でも)に読み取り、書き込み、削除権限を付与
-
private/[認証ユーザーのID]/*
- 対象の認証ユーザー(作成者)に読み取り、書き込み、削除権限を付与(作成者専用)
- 作成者以外のユーザーは権限がないので見えない
アクセス制御の詳細については、公式ドキュメントを確認してください。
import { defineStorage } from "@aws-amplify/backend";
export const storage = defineStorage({
name: "remix-storage-browser",
access: (allow) => ({
"public/*": [
allow.guest.to(["read"]),
allow.authenticated.to(["read", "write", "delete"]),
],
"private/{entity_id}/*": [
allow.entity("identity").to(["read", "write", "delete"]),
],
}),
});
バックエンドのリソースに作成した、storage
を追加します。
import { defineBackend } from "@aws-amplify/backend";
import { auth } from "./auth/resource";
+ import { storage } from "./storage/resource";
defineBackend({
auth,
+ storage,
});
リソースを作成
以下のコマンドを実行して、個人の sandbox 環境に定義したリソースを作成します。
npx ampx sandbox
リソースが作成されると、amplify_outputs.json
が作成されます。ファイルには、作成されたリソースの情報が記述されているので、意図したリソースが作成されているかを確認してみてください。
Storage Browser コンポーネントを配置
リソースが作成できたら、Storage Browser コンポーネントをページに配置します。
ドキュメントで提供されているサンプルの通り、設定すれば問題なく表示できることを確認できました。Amplify auth を利用したこともあって、すごく楽ですね。
コンポーネントをカスタマイズしたい場合は、コンポーネントの props を設定することで実施できそうです。カスタマイズの詳細は、公式ドキュメントをご確認ください。
import { Amplify } from "aws-amplify";
// npx ampx sandbox コマンドで作成された amplify_outputs.json ファイルをインポート
import config from "../../amplify_outputs.json";
import {
createAmplifyAuthAdapter,
createStorageBrowser,
} from "@aws-amplify/ui-react-storage/browser";
import { Authenticator } from "@aws-amplify/ui-react";
// Amplify.configure(config) を呼び出して、Amplify を設定
Amplify.configure(config);
export const { StorageBrowser } = createStorageBrowser({
// Amplify auth を利用した場合は createAmplifyAuthAdapter() を使用
config: createAmplifyAuthAdapter(),
});
export default function Index() {
return (
// 認証を必須にしたい場合、Authenticator コンポーネントでラップ
<Authenticator>
<StorageBrowser />
</Authenticator>
);
}
動作確認
コンポーネントを配置した画面を表示して、動作確認してみます。
ログインしてから表示
Authenticator
でラップしたコンポーネントを表示すると、未ログインの場合 Cognito のログインを求められる(Amplify auth の機能)ので、登録したユーザーでログインします。
ログイン後にページを表示すると以下のように、private/[認証ユーザーのID]/*
, public/*
フォルダへのアクセス権が、読み取り、書き込みが付与されていることを確認できました。
private/[認証ユーザーのID]/*
フォルダに、ファイルやフォルダをアップロードすることを確認できました。また、検索、オブジェクトの削除、オブジェクトのコピーなどできることを確認できました。一通りの必要な操作が Storage Browser コンポーネントだけでできそうですね。
未ログインで表示
次に未ログインの状態(匿名ユーザー)で、表示してみます。
public/*
フォルダへの読み取りアクセス権のみとなっていることを確認できました。
意図した動きになってそうですね。
さいごに
Storage Browser を使うことで、簡単に S3 のオブジェクトの操作を Web アプリに組み込めそうでした。自前で実装するよりは遥かに楽に組み込めるので、今後、利用する機会が増えるかもしれないですね。
各種サンプルは、React をベースとしていたので、Remix でも使えるだろうと思い、今回は実際に構築するところまで、試してみました。
Storage Browser を既存の仕組みに組み込む場合は、既存の S3 バケットに組み込むパターンや各種カスタマイズすることが多いかと思うので、引き続き試してみようと思います。
参考