StorageBrowser for AWS S3をAmplifyでカスタム認証+既存S3バケットで使う手順
はじめに
Cursorで作業した内容を記事にまとめるのにもう人間の手は入らないでもいいんだな、、、という気持ちでいっぱいですが、こういう知見を共有するのはいいことだし記事を書くのに時間かけてると本末転倒(楽しいけど)なので、良いことだな、、と文章の枕元にを妙に書いてしまう今日この頃ですがいかがお過ごしですか?
というわけで、タイトルの用にAmplify Gen1を使ってWEBアプリケーションの運用・保守を行なっているのですが、管理者画面からS3の特定のディレクトリにファイルをアップロードしたい、という要望がありました。要件を簡単にまとめると
- webアプリでログインしてるユーザーの認証を使ってファイル操作をしたい(今回は特定のグループに所属してれば利用できる、という条件で実装しました)
- バケットは
amplify add storage
したものではなく、別途任意で作られたバケットを指定したい
という感じです。はじめの時点では「Amplify.configureに設定を追加してあげれば良いかな」と軽く考えてたんですが、configがそもそもamplifyconfiguration.json
にない(add storage
してないんだからそれはそう。でもadd storage
はしたくない)のでどうにもうまくいかなったです。で、考えてみたらStorageBrowser for AWS S3って独立したサービスページがあるくらいなので、別にAmplifyにこだわらずとも使えるのでは?という当たり前のことに気がつきました。
で、ドキュメントを読んでみるとカスタム認証やバケットの指定がそもそもできるのでAmplifyと切り離して設定を行うことができるわけです。
ならそれで進めようとCursorとああでもないこうでもないと進めたところ下記の内容になりました。
アクセスできるようになってみるとStorageBrowser自体は大変便利ですね。
では以下にやったことをまとめてもらったのでそちらをご覧ください。
ーーーーここからーーーー
AWS AmplifyのStorageBrowserは、S3バケットのファイルをWeb UIで管理できる便利なコンポーネントです。Amplify CLIで管理されたバケット以外にも、既存のS3バケットやカスタム認証と組み合わせて利用することができます。本記事では、Next.js(App Router)環境を例に、カスタム認証で既存バケットをStorageBrowserで操作する手順を解説します。
必要なパッケージのインストール
npm install aws-amplify @aws-amplify/ui-react-storage
Amplifyの基本設定
Amplify.configure()
でCognitoなどの認証情報を設定します。
(この部分は通常のAmplify Authのセットアップと同じです)
StorageBrowser用のカスタム認証設定
Amplify StorageBrowserのcreateStorageBrowser
に、カスタム認証用のconfigを渡します。
import { fetchAuthSession } from 'aws-amplify/auth'
import { createStorageBrowser } from '@aws-amplify/ui-react-storage/browser'
export function StorageBrowserComponent() {
const { StorageBrowser } = createStorageBrowser({
config: {
listLocations: getS3Locations,
getLocationCredentials: getLocationCredentials,
registerAuthListener: () => () => {},
region: 'ap-northeast-1', // 利用するリージョン
},
})
return <StorageBrowser />
}
S3ロケーション情報の提供
listLocations
関数で、ユーザーに見せたいS3バケットやプレフィックス(フォルダ)を返します。
各ロケーションにはid
・bucket
・prefix
・type
・displayName
・permissions
を指定します。
async function getS3Locations() {
return {
items: [
{
id: 'example-folder',
bucket: 'your-bucket-name',
prefix: 'your-prefix/',
type: 'PREFIX' as const,
displayName: '表示名',
permissions: ['delete', 'get', 'list', 'write'] as Array<'delete' | 'get' | 'list' | 'write'>,
},
// 必要な分だけ追加
],
nextToken: undefined,
}
}
S3アクセス用の一時認証情報の提供
getLocationCredentials
関数で、Amplify Auth経由で取得した一時クレデンシャルを返します。
const getLocationCredentials = async (input: any) => {
const session = await fetchAuthSession()
if (!session.credentials) throw new Error('No credentials')
return {
credentials: {
accessKeyId: session.credentials.accessKeyId,
secretAccessKey: session.credentials.secretAccessKey,
sessionToken: session.credentials.sessionToken || '',
expiration: session.credentials.expiration || new Date(Date.now() + 3600000),
},
expiration: session.credentials.expiration || new Date(Date.now() + 3600000),
}
}
S3バケットのCORS設定
S3バケットに以下のようなCORS設定を適用します。
(AllowedOrigins
は自分のアプリのURLに合わせて調整)
{
"CORSRules": [
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "HEAD", "PUT", "POST", "DELETE"],
"AllowedOrigins": [
"http://localhost:3000",
"https://your-app-domain.com"
],
"ExposeHeaders": [
"last-modified",
"content-type",
"content-length",
"etag",
"x-amz-version-id",
"x-amz-request-id",
"x-amz-id-2",
"x-amz-cf-id",
"x-amz-storage-class",
"date",
"access-control-expose-headers"
],
"MaxAgeSeconds": 3000
}
]
}
適用コマンド例:
aws s3api put-bucket-cors --bucket your-bucket-name --cors-configuration file://cors-policy.json
動作確認
- アプリを起動し、StorageBrowser画面を開く
- フォルダをクリックしてファイル一覧を表示
- ファイルを選択し、アクションメニューから「Download」等の操作ができることを確認
まとめ
Amplify StorageBrowserは、カスタム認証と既存S3バケットの組み合わせでも柔軟に利用できます。
ポイントは「listLocations」「getLocationCredentials」のカスタマイズと、S3バケットのCORS設定です。
参考:
ーーーーここまでーーーー
実際にやってみたらそれほど大きな手間がかからずにUIを備えたファイル管理の仕組みが出来たのでこれは便利ですね。UI自体のカスタムも出来るみたいです。
というわけで、Amplifyで100万超えたユーザー数のウェブサービスを運用保守してるんですが、比較的Amplifyの箱庭の中でやれることは多いので、何かご依頼があれば気軽に こちらまで にご連絡ください。その際はこの記事を読んだよ、と教えてくれると話が早いと思います。
Discussion