React+Amplify+Cognito認証のアプリで画像ファイルをS3にアップロードする


はじめに

前の記事で、React+Amplify+Cognito認証のアプリで自動デプロイするところまでご紹介しました。

www.aruse.net

今度は、Amplify の Storage という機能を使用して S3 にファイルをアップロードする方法をご紹介します。

前の記事のプロジェクトに機能を追加していくので、必要に応じて参照してください。

Amplify の Storage 機能追加

現在のプロジェクトに、Amplify の Storage 機能を追加します。

といってもコマンドの質問に答えていくだけですが。

$ amplify add storage
? Please select from one of the below mentioned services Content (Images, audio, video, etc.)
? Please provide a friendly name for your resource that will be used to label this category in th
e project: s3xxxxxx
? Please provide bucket name: deploy-appxxxxxxxxxxxxxxxxxxxxxxxx
? Who should have access: Auth users only
? What kind of access do you want for Authenticated users? create/update, read
? Do you want to add a Lambda Trigger for your S3 Bucket? No

$ amplify push

React の実装

これで Amplify の準備はできたので、次は React の実装を行います。

今回は画像ファイルをアップロードするということで、Amplify の UI コンポーネントのPhotoPickerを使用します。

PhotoPickerは画像をドラッグ&ドロップで取得できるだけでなく、アップロード後にプレビュー表示してくれる優れものです。

App.tsxのソースコードは以下のようになります。

import React from 'react';
import { withAuthenticator } from "aws-amplify-react";
import { PhotoPicker } from 'aws-amplify-react';
import { Storage, Auth } from 'aws-amplify';

const App: React.FC = () => {

  return (
    <>
      <button onClick={() => Auth.signOut()}>サインアウト</button>
      <PhotoPicker preview onPick={data =>{ 
        const { file } = data;
        Storage.put(file.name, file,{
          level: 'private',
          contentType: file.type
        })
        .then (result => console.log(result)) 
        .catch(err => console.log(err));

      }
    } onLoad={dataURL => console.log(dataURL)} />
  </>
  );
}

// Cognito認証
export default withAuthenticator(App);

ポイントは、Storage.putの部分で画像ファイルを S3 にアップロードしていることです。その際、他のユーザーからファイルを参照できないよう、レベルをprivateにしています。

また、export default withAuthenticator(App);のように、AppwithAuthenticatorで囲むとアプリケーション全体が Cognito 認証の配下となり、サインインしないと最初の画面も表示されません。

では、実際にアプリケーションを起動してみます。

$ yarn start

認証画面が予定通り表示されました。

f:id:fnyablog:20190714142931p:plain:w480

サインインを行うと、以下のように画像ファイルのアップロード画面が表示されます。

f:id:fnyablog:20190714143111p:plain:w480

画像ファイルをドラッグ&ドロップすると、S3 にファイルアップロード後に画像ファイルがプレビュー表示されます。

f:id:fnyablog:20190714143147p:plain:w480

S3 の管理画面で確認すると、ユーザーのプライベート領域(「private」配下)に画像ファイルが正しくアップロードされていることが分かります。

f:id:fnyablog:20190714143301p:plain:w480

Cognito のユーザーでアクセス権が制御されているため、URL をリンクしてもアクセス拒否されてしまいますが、管理者権限でファイルをダウンロードして表示すると、以下のように問題なく表示できることが確認できます。

f:id:fnyablog:20190714143534p:plain:w320

念のため、前の記事で設定したようにリモートリポジトリにpushしたら自動デプロイされて動作するかも確認します。

$ git add .
$ git commit -m "Add storage."
$ git push origin master

デプロイ先のアドレスにアクセスすると、認証画面がちゃんと表示されますね。

f:id:fnyablog:20190714143931p:plain:w480

サインインして画像ファイルをアップロードすると、画像プレビューも正しくされました。

f:id:fnyablog:20190714144055p:plain:w480

S3 のファイルのタイムスタンプを確認すると、ファイルが上書きされていることが分かります。

・アップロード前

f:id:fnyablog:20190714144207p:plain:w480

・アップロード後

f:id:fnyablog:20190714144230p:plain:w480

おわりに

React + Amplify + Congnitで S3 に画像ファイルをアップロードするのが簡単だということが分かったと思います。

Amplify の活用範囲が広がっていきますね。

参考サイト

omuriceman.hatenablog.com