ReactアプリからAWS S3に画像ファイルをアップロードする方法

AWS

やりたいこと

今回は、ReactアプリケーションからAWS S3に画像ファイルをアップロードする方法を紹介します。AWS S3はクラウドストレージサービスで、大量のデータやファイルを安全に保管できるため、画像やドキュメントの保存先として多くのアプリケーションで利用されています。

この記事では、AWS SDKを使って画像をS3にアップロードする具体的な手順を、初心者向けに詳しく説明します。


AWS S3に画像をアップロードするための準備

AWSアカウントの準備

まずは、AWSアカウントを作成し、S3バケットを作成します。

  1. AWS Management Consoleにサインインし、S3を検索して選択します。
  2. S3のダッシュボードで「バケットを作成」をクリックし、バケット名を設定します。
  3. ここでは、バケット名を「my-image-bucket」に設定するとします。

IAMユーザーの作成と権限の設定

AWS SDKを使用してS3にファイルをアップロードするには、IAMユーザーを作成し、そのユーザーに適切な権限を設定する必要があります。

  1. IAMを検索し、ダッシュボードから「ユーザーの追加」を選択します。
  2. 必要な権限を持つユーザーを作成し、AmazonS3FullAccessポリシーをアタッチします。
  3. 作成後、アクセスキーIDシークレットアクセスキーをメモします。これらを後でReactアプリに設定します。

ReactプロジェクトにAWS SDKを導入

AWS SDKのインストール

ReactアプリでAWS S3を操作するために、まずはAWS SDKをインストールします。

Bash
npm install aws-sdk

環境変数の設定

次に、AWSの認証情報(AWS_KEYAWS_SECRET_KEY)やバケット名を環境変数に設定します。これにより、セキュアにアクセス情報を管理できます。

.envファイルに以下を追加します。

Bash
REACT_APP_AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID
REACT_APP_AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY
REACT_APP_AWS_REGION=us-east-1
REACT_APP_AWS_BUCKET_NAME=my-image-bucket

環境変数は、process.envを使ってアプリ内でアクセスできます。


Reactで画像ファイルをアップロード

AWS SDKを使ってS3に画像をアップロード

Reactアプリケーションから画像をS3にアップロードするためのコードを実装します。

TypeScript
// 必要なAWSモジュールをインポート
import AWS from 'aws-sdk';
import { Credentials } from 'aws-sdk';

// S3に画像をアップロードする関数
export const s3Upload = (selectedFile: File): Promise<boolean> => {
  // 認証情報を設定
  const creds = new Credentials(
    process.env.REACT_APP_AWS_ACCESS_KEY_ID!,
    process.env.REACT_APP_AWS_SECRET_ACCESS_KEY!
  );

  // S3インスタンスを生成
  const s3 = new AWS.S3({
    region: process.env.REACT_APP_AWS_REGION,
    credentials: creds,
  });

  // S3にアップロードする際のパラメータを設定
  const fileName = 'uploads/' + selectedFile.name; // アップロード先フォルダを指定
  const uploadParams = {
    Bucket: process.env.REACT_APP_AWS_BUCKET_NAME!,
    Key: fileName,
    Body: selectedFile,
  };

  // 非同期でアップロード処理を実行
  return new Promise<boolean>((resolve, reject) => {
    s3.upload(uploadParams, (err, data) => {
      if (err) {
        console.error('Error uploading file:', err);
        reject(err);
      } else {
        console.log('File uploaded successfully:', data);
        resolve(true);
      }
    });
  });
};

アップロードフォームの実装

次に、画像ファイルを選択してS3にアップロードするフォームを実装します。

TypeScript
import React, { useState } from 'react';
import { s3Upload } from './s3Upload'; // 先ほど作成したs3Upload関数をインポート

const FileUpload = () => {
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [message, setMessage] = useState<string>('');

  // ファイルが選択されたときに呼び出されるハンドラ
  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    if (event.target.files && event.target.files.length > 0) {
      setSelectedFile(event.target.files[0]);
    }
  };

  // ファイルをS3にアップロードするハンドラ
  const handleUpload = async () => {
    if (selectedFile) {
      try {
        await s3Upload(selectedFile);
        setMessage('ファイルのアップロードに成功しました!');
      } catch (error) {
        setMessage('アップロードに失敗しました。');
      }
    } else {
      setMessage('ファイルを選択してください。');
    }
  };

  return (
    <div>
      <h2>画像ファイルをS3にアップロード</h2>
      <input type="file" onChange={handleFileChange} />
      <button onClick={handleUpload}>アップロード</button>
      {message && <p>{message}</p>}
    </div>
  );
};

export default FileUpload;

エラー処理と改善ポイント

画像やファイルのアップロードには、いくつかの注意点や改善ポイントがあります。

エラーハンドリングの追加

ファイルのアップロード中にエラーが発生した場合、ユーザーにフィードバックを提供するためのエラーハンドリングを強化することが重要です。上記のコードでは、try-catch文を使用して、アップロード失敗時にメッセージを表示しています。

進行状況の表示

ファイルが大きい場合、ユーザーにアップロードの進行状況を知らせることが求められます。S3のuploadメソッドには、progressイベントを利用して進行状況を表示できます。

TypeScript
s3.upload(uploadParams)
  .on('httpUploadProgress', (evt) => {
    console.log('Upload Progress:', Math.round((evt.loaded / evt.total) * 100) + '%');
  })
  .send((err, data) => {
    // 完了後の処理
  });

セキュリティ考慮

S3バケットや認証情報は、セキュリティの観点から慎重に管理する必要があります。アップロード処理に直接AWS_SECRET_KEYを使うことは避け、CognitoIAMロールを使用してセキュリティを強化することをおすすめします。


感想

今回、ReactアプリからAWSのS3に画像ファイルをアップロードする機能を実装しました。S3を利用することで、クラウド上で安全かつ効率的にファイルを保存できるため、ファイル共有機能を含む多くのアプリケーションで役立ちます。

今回の実装で学んだことを基に、さらに高度なアップロード機能(ファイルの進行状況の表示、エラーハンドリングの強化など)も取り入れながら、よりユーザーフレンドリーなアプリにしていきましょう。

今回の内容が参考になったら幸いです。

コメント

タイトルとURLをコピーしました