質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.36%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

3076閲覧

node.jsでS3バケットの任意のファイルをダウンロードできるWebアプリを作りたいです。

hanju8810tt

総合スコア16

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

0クリップ

投稿2020/08/31 03:18

編集2020/08/31 07:42

ファイルを2つ作成しました。
test.html s3バケットから任意のファイルをダウンロードするためのUI
init.js AWS Credentials情報などを記載

イメージ説明
■操作方法
ListBuckets(Button)・・押下すると、設定済みのS3バケット内が一覧表示される
File Name(TextBox)・・ファイル名を入力する
DownLoad(Button)・・押下すると、File Nameに入力したファイルが存在すればそのファイルがダウンロードされる。

■質問したいこと
下のコードで、「 //↑ここでファイルをダウンロードしたい」の箇所にS3バケットからファイルをダウンロードする
コードを記述したいです。どうかご教示願います。

■試したこと
コマンドプロントからaws cliを使って任意のファイルをダウンロードするコマンドを作成しました。
aws s3 cp s3://<バケット名>/<ファイル名> <ダウンロード先>

上記コマンドを実行する関数を作成しました。
function s3cpfile(funcbn,funcpre2){
funcbn=BUCKET_NAME;
funcpre2=prefix2; //←File Name(TextBox)の値です。
return "aws s3 cp s3://" + funcbn + "/" + funcpre2 +" " + "." ;
}

これを実行したいのですが、(修正版)test.htmlでは実現できません。コマンドラインはあっています。

(修正版)test.html

<!DOCTYPE html> <html> <head> <title>S3getFile</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script type="text/javascript" src="http://sdk.amazonaws.com/js/aws-sdk-2.0.0-rc13.min.js"></script> <script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript" src="./init.js"></script> </head> <body> <h1> バケットネーム </h1> Search Directory:<input type="text" id="text1"> <button id="btn1">ListBuckets</button> <div><div>File Name:<input type="text" id="text2"> <button id="btn2">Down Load</button></div></div> <div id="status">Result</div> <div id="objects">List</div> <script type="text/javascript">//<![CDATA[ $(function() { $("#btn1").click( function() { $("#objects").html(""); var prefix = $("#text1").val(); if( prefix && prefix[prefix.length-1] != "/" ) prefix += "/"; var params = { Bucket: BUCKET_NAME, Delimiter: "/", Prefix: prefix }; s3.listObjects(params, function (err, data) { if (err) { document.getElementById("status").innerHTML = "Could not load objects from S3 " + (err); } else { console.dir(data); var count = 0; // フォルダを表示 for (var i = 0; i < data.CommonPrefixes.length; i++) { document.getElementById("objects").innerHTML += "<li>[" + data.CommonPrefixes[i].Prefix + "]</li>"; ++count; } // ファイルを表示 for (var i = 0; i < data.Contents.length; i++) { var c = data.Contents[i]; if( c.Key[c.Key.length-1] == "/" ) continue; document.getElementById("objects").innerHTML += "<li>" + data.Contents[i].Key + "</li>"; ++count; } document.getElementById("status").innerHTML = "Loaded " + count + " items from current"; } }); }); }); $(function() { $("#btn2").click( function() { var prefix2= $("#text2").val(); if (prefix2 ==""){ document.getElementById("status").innerHTML = "Please enter a file name."; } else { //ファイルを検索 var params2 = { Bucket: BUCKET_NAME, Key: prefix2, }; s3.getObject(params2, function(err, data) { if (err) { document.getElementById("status").innerHTML = "NG! "+ err } else { function s3cpfile(funcbn,funcpre2){ funcbn=BUCKET_NAME; funcpre2=prefix2; return "aws s3 cp s3://" + funcbn + "/" + funcpre2 +" " + "." ;             }             s3cpfile(); }}) } }); }); //]]></script> </body> </html>

init.js

var BUCKET_NAME = "バケットネーム"; AWS.config.update({ accessKeyId: "アクセスキー", secretAccessKey: "シークレットアクセスキー" }); AWS.config.region = "ap-northeast-1"; var s3 = new AWS.S3({params: {Bucket: BUCKET_NAME}});

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hanju8810tt

2020/08/31 07:26

具体的に、aws s3 cpコマンドを追加しました。
hanju8810tt

2020/08/31 08:58

回答ありがとうございます。流れとしては以下を考えています。 この実装でS3バケットからシームレスにファイルをダウンロードできる機能を実装する。 ↓ Lambda化して、APIエンドポイントから本機能を使えるようにする。 CrowdFomation(SAM)で、AWSインフラ側を構築し、IAMでこのLambda関数に妥当な権限を付与する予定でいました。
guest

回答1

0

ベストアンサー

そもそもこの実装自体をやめることをお勧めします。
クライアント側で動かすJSにアクセスキーとシークレットキーを埋め込むと、クライアントにアクセスキーとシークレットキーが渡されてしまいます。
ということは、サイトにアクセスした不特定多数に対してあなたのAWSアカウントのキーを配ってしまうことになります。
アクセスキーとシークレットキーを渡してしまうと、そのキーの権限を使ってあなたのAWSアカウントのリソースをどこからでも操作されてしまいます。
もしキーの権限を絞ってなかったりするとあっという間に悪用されます。

まず前提として、JacaScriptはクライアント側で動かす、ということを理解する必要があります。
※サーバサイドで動かすNode.jsについてはここでは範疇の外なので割愛します。

単に今回のことを実現したいだけならただSDKを使うのが手っ取り早いです。
Class: AWS.S3
cliのコマンドを埋め込んだところで、クライアントでcliを確実に動作させる術がないです。
アクセスする人が必ずcliを入れている保証は全く無いですし。

前述の通りアクセスキーを埋め込むとセキュリティ的に問題があるので、クライアントからS3にアクセスさせたいのであればAPIを経由してpre-signed URLを発行するか、適切に認証を挟むなど工夫が必要です。
認証を挟んでS3バケットにアクセスさせる実装についてはサンプルがあります。
ブラウザからの Amazon S3 バケット内の写真の表示
※このサンプルはListObjectしか使っていないので、あくまで参考です。

投稿2020/08/31 08:42

yu_1985

総合スコア7586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hanju8810tt

2020/08/31 09:00

回答ありがとうございます。流れとしては以下を考えています。 この実装でS3バケットからシームレスにファイルをダウンロードできる機能を実装する。 ↓ Lambda化して、APIエンドポイントから本機能を使えるようにする。 CrowdFomation(SAM)で、AWSインフラ側を構築し、IAMでこのLambda関数に妥当な権限を付与する予定でいました。
yu_1985

2020/08/31 09:07

最終形がそれであれば、どのみちこの実装では実現できないですね。 というよりも、その矢印の間で実装が変わってしまいます。 HTMLはクライアントに渡す一方、Lambdaはクライアント側で動くものではないので。 やり方としては結局APIを経由して動かすのと大差ありません。 APIから使えるようにするのであればなおさらコマンドを埋め込んでも仕方ありません。 その部分でやるべきはAPIにリクエストを送ることです。 その上で、本当にただやるだけでいいのであれば素直にクライアント側でSDKを動かすのが手っ取り早いでしょう。 APIを経由する形にするときに、リクエストを投げる形にすればよいので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問