【Vue.js】AWS-S3へ簡単にファイルをアップロードする方法
こんにちは、タロウです。
vueで作成したアプリケーションをAWSで稼働させる機会があり、
今後使う機会が増えそうなので書き残します!
S3にファイルをアップロードする際、大きく2つの方法で迷います。
- クライアントサイドから直接S3にアップロードさせる
- クライアントサイドからサーバAPIを経由してS3にアップロード
どっちで実装しよう。。
クライアントサイドから直接S3にアップロードさせる
クライアント側にS3のアクセスキーを持たなければいけないためセキュリティリスクが高いです。
それも承知の上・・であれば、期限付きURLを発行して直接アップロードさせる方法が良いです。
クライアントサイドからサーバAPIを経由してS3にアップロード
今回はこちらの方法を書き留めます。(これを実装すれば直接アップロードも機能を削るだけで出来ます)
クライアントサイド、サーバAPIのS3の連携部分と分けて解説します!
完成形
ぼく、水彩画の線結構好き。
もくじ
- バケットの準備
- プラグインを入れよう
- クライアントサイド
- サーバサイドAPI
バケットの準備
AWSコンソールにログインしてS3の設定画面からバケットを作成します。
バケット名とリージョンを設定して、あとはデフォルトのまま進めます。
(パブリックアクセスはOFFにしておきます)
プラグインを入れよう
AWSでnodejs用のプラグインが準備されているので、インストールします。
npm install --save aws-sdk fs
AWSを操作するためのライブラリと、
nodejsでファイル操作を行うためのライブラリをインストールします。
クライアントサイド
最低限のファイル選択と、ボタンを配置してます。
methods内の処理がポイントです!
<template>
<div id="app" class="family">
ファイルを選択
<input @change="changeFile" ref="rfafile" type="file" />
<input @click="regist" type="button" value="Upload"/>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
uploadfile: {},
};
},
methods: {
changeFile(e) {
const files = e.target.files || e.dataTransfer.files;
// ファイルが選択されたら変数に入れる
this.uploadfile = files[0];
},
// 送信アクション
async regist() {
// パラメータ生成
var params = new FormData();
// FormDataにアップロードするファイルを設定
params.append('file', this.uploadfile);
// API実行
let { data } = await axios.post(
'/' + process.env.API_PATH + '/hoge/fileUpload',
params,
{
headers: {
// multipartで送信
'content-type': 'multipart/form-data',
},
}
);
},
},
};
</script>
<style>
</style>
axiosでExpressjsで作成したAPIを呼ぶようにしてます。
サーバサイド
Vueから受けとったファイルをS3にアップロードする処理を実装します。
npmでインストールしたaws-sdkを使用するとすごく簡単です。
var AWS = require('aws-sdk');
var bodyParser = require('body-parser');
var multer = require('multer');
// アップロードされたファイルの一時格納フォルダ
var upload = multer({ dest: '/tmp/express/uploads/' });
var fs = require('fs');
// AWSのアクセスキーをjsonで記載
AWS.config.loadFromPath('config/aws-credentials.json');
// リージョンを指定
AWS.config.update({ region: 'ap-northeast-1' });
module.exports = function(app) {
// API設定
var path = '/aws';
// POSTパラメータの受取
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// アップロードAPI
app.post(path + '/fileUpload', upload.single('file'), async function(
req,
res
) {
// S3のインスタンスを生成
var s3 = new AWS.S3();
// アップロード用のパラメータを設定
var params = {
// バケット名
Bucket: 'test',
// アップロード後のファイル名(hogehoge/uploadfile.png などのディレクトリ指定も可)
Key: req.file.originalname,
};
// fsで一時ディレクトリにアップロードされたファイルを読み込み
var v = fs.readFileSync(req.file.path, (err, data) => {
return data;
});
// パラメータに設定
params.Body = v;
// ファイルアップロード処理実行
s3.putObject(params, function(err, data) {
if (err) {
console.log(err, err.message);
} else {
console.log("アップロード成功!");
}
});
});
};
実装は以上になります!
画面からファイルを選択しアップロードするとS3にファイルがアップロードされているはずです!
余談:
S3にアップロードしたファイルを期限付きURLを発行して参照する方法も紹介します。
// 期限付きURL取得(900:15分)
// パラメータを設定
var getUrlparams = {
// バケット名
Bucket: 'test',
// S3に格納済みのファイル名
Key: "hoge.png",
// 期限(秒数)
Expires: 900,
};
// URL発行
s3.getSignedUrl('getObject', getUrlparams, function(err, url) {
console.log('期限付きURL:', url);
});
グローバルにしたくない・・けど、ユーザーにS3から直接ダウンロードさせたい・・時などに使えます!
昔にPHPでも実装したので、PHP版はこちらをご参照ください!
まとめ
S3へのアクセスでよく使いそうなロジックを実装してみました!
ほかにもファイル一覧を返却したり、削除したりと一通りの操作が簡単に実装できます。
AWSを使っている現場にはメジャーなプラグインかもしれませんが、ご紹介でした!