この記事ではpresigned URLを使用してs3に画像を保存、表示する方法を学んでいきます。
Presigned Urlとは?
presigned URLは、特定のS3オブジェクトへの一時的なアクセスを許可するために,
ユーザーに提供することができるURLです。URLを使用して、ユーザーはオブジェクトをREADするか、オブジェクトをWRITEする(または既存のオブジェクトを更新する)ことができます。
環境,事前準備
- "aws-sdk": "^2.1116.0"
- バックエンド(express(Node.js)), フロント(vue, react, angluar, Svelte etc)
- awsのアクセスキー (IAMでs3の操作権限を持つユーザーを作成し、アクセスキーを取得してください)
- s3にbucketを作成
Presigned Urlを作成するAPI
const AWS = require("aws-sdk");
const uuid = require("uuid/v4");
const s3 = new AWS.S3({
accessKeyId: "Your AWS accessKeyId",
secretAccessKey: "Your secretAccessKey",
region: "your region(東京を選んでいる場合はap-northeast-1)",
});
module.exports = async (app) => {
app.get("/api/upload", async (req, res) => {
const key = `${req.user.id}/${uuid()}.jpeg`;
const url = s3.getSignedUrl("putObject", {
Bucket: "Your bucket name",
ContentType: "image/*",
Key: key,
});
console.log(key);
res.send({ url, key });
});
};
フロント(JavaScript) /api/uploadを叩いて画像をs3に保存する処理
//apiからurlとkeyを取得
const uploadConfig = await axios.get("/api/upload");
//取得したurlをもとにs3に画像を保存(引数fileには<input type="file">で取得した画像が入る)
try {
await axios.put(uploadConfig.data.url, file, {
headers: {
"Content-Type": "image/*",
},
});
} catch (err) {
console.log(err);
}
**画像保存時にCORSエラーが表示されるため、s3のCORS設定を下記画像のように変更する
web上に画像を表示させる
//東京の場合 your selected region は ap-northeast-1 になります。
//keyはapiで作成したkeyが入ります。(const key = `${req.user.id}/${uuid()}.jpeg`;)
const imageUrl = `https://<your bucket name>.s3.<your selected region>.amazonaws.com/<key>`;
<img src={imageUrl} alt="blog" />
**もし画像が表示できない場合,Bucket policyが原因かも知れません。下記のようにBucket policyを変更するとweb上で保存した画像を閲覧することができます。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::test123ta/*"
}
]
}
s3上に画像、ファイルを保存することは実務でもよく使うかと思います!この記事で得た技術を応用し、使用していだだけたら幸いです!お読みいただきありがとうございます!