🍊

Next.jsでS3からJSONデータを取得する方法

2024/02/08に公開

はじめに

完成イメージ
コンソールでjsonの内容が確認できる。

フロントエンドの環境は、下記の記事で作成した基本的な環境を使用しています。
https://zenn.dev/nenenemo/articles/082ac7dcffe308

なお、この方法は開発ツールのNetworkタブで認証情報が確認できてしまうため、AWSの認証情報が誰でも見れてしまいますので推奨しません。

S3の作成

バケットを作成を選択、

バケット名を入力し、そのほかは特に変更せず、下へスクロールしバケットを作成を選択してください。

jsonをアップロードする

今回使用するtest.jsonの内容は以下です。

{
  "title": "Python入門",
  "price": 2500
}

オブジェクトに直接jsonをアップロードしてください。

アップロードを選択してください。

オブジェクトのキー

オブジェクトを選択

オブジェクトの概要 > キーがオブジェクトのパスになります。

AWS SDK のインストール

今回使用する方
AWS SDKの全体をインストールして、全てのAWSサービスにアクセスするために必要なAWS SDKの全てのモジュールをインストールする。

 npm install aws-sdk

または、S3クライアントを使用するためのAWS SDKの一部を個別にインストールする方法がありますが、この場合は今回紹介するの記述方法とは異なります。
https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/javascript_s3_code_examples.html

npm install @aws-sdk/client-s3

CORSの有効化

https://repost.aws/ja/knowledge-center/s3-configure-cors

AWS CLIを使用する方法

aws s3api put-bucket-cors --bucket <バスケット名> --cors-configuration '{"CORSRules" : [{"AllowedHeaders":["*"],"AllowedMethods":["GET","HEAD"],"AllowedOrigins":["<S3のデータを取得するサイトのドメイン>"],"ExposeHeaders":["Access-Control-Allow-Origin"]}]}'

コンソールから

Amazon S3 > バケット > バスケットを選択
アクセス許可を選択

下にスクロールするとCross-Origin Resource Sharing (CORS)があるので``を選択、

下記を入力したら、変更を保存を選択してください。

[
  {
    "AllowedHeaders": [
      "*"
    ],
    "AllowedMethods": [
      "GET",
      "HEAD"
    ],
    "AllowedOrigins": [
      "<S3のデータを取得するサイトのドメイン>"
    ],
    "ExposeHeaders": [
      "Access-Control-Allow-Origin"
    ]
  }
]

AllowedHeaders:ワイルドカードを使用していますが、リクエストを送信する際に利用するヘッダーを登録する箇所
AllowedMethods:今回は取得なので "GET", "HEAD"

CORSの有効化を確認する

curl -i http://<バスケット名>.s3.<リージョン名>.amazonaws.com/<オブジェクトのパス> -H "Origin: <S3のデータを取得するサイトのドメイン>"

または、メソッドを選択して確認してください。

curl -i http://<バスケット名>.s3.<リージョン名>.amazonaws.com/<オブジェクトのパス> -H "Access-Control-Request-Method: POST" --request OPTIONS -H "Origin: <S3のデータを取得するサイトのドメイン>"

フロントエンド

.envも設定してください。

page.tsx
'use client';

import AWS from 'aws-sdk';
import useEffect from 'react';

export default function Home() {
 useEffect(() => {
    const s3 = new AWS.S3({
      accessKeyId: process.env.NEXT_PUBLIC_ACCESS_KEY_ID || '',
      secretAccessKey: process.env.NEXT_PUBLIC_SECRET_ACCESS_KEY || '',
      region: process.env.NEXT_PUBLIC_REGION || '',
    });

    const params = {
      Bucket: process.env.NEXT_PUBLIC_BUCKET || '',
      Key: process.env.NEXT_PUBLIC_KEY || '',
    };

    s3.getObject(params, (err, data) => {
      if (err) {
        console.error(err);
      } else {
        if (data.Body) {
          console.log(
            'data',
            JSON.stringify(JSON.parse(data.Body.toString()), null, 2)
          );
        }
      }
    });
  }, []);
}

参考にさせていただきました

https://qiita.com/taisuke101700/items/d7efaca27b33adf29833
https://dennie.tokyo/it/?p=3791
https://qiita.com/oblivion/items/bac8479852d4cc92941d

終わりに

何かありましたらお気軽にコメント等いただけると助かります。
ここまでお読みいただきありがとうございます🎉

Discussion