Cooking Frontend . Image Uploader . Upload Image to S3 through AWS Javascript SDK
Sep 1, 2018 · 6 min read

上傳照片是軟體服務裡很常見的一種功能,做法也百百種,而利用 AWS S3 的空間和 SDK 來實作是很常見的做法,這裡我們就是要用 AWS Javascript SDK 來實作從 Browser 直接將照片上傳到 AWS S3。
在有 SDK 的情況下 Frontend 的部分並不難,但 Frontend 平常較少接觸的 AWS 部分可能就很容易忘記該怎麼設定 (ex: IAM),又或者沒跟上新的改變 (ex: Cognito),所以這篇會著重在 AWS 的設定細節。
- AWS Setting Up (Developer Guide)
- S3 . Bucket
- Cognito . Identity Pools
- IAM - Frontend Getting Started
- AWS Javascript SDK
- <input type=”file”> and s3.upload()
AWS Setting Up
S3 . Bucket
- 首先我們在 S3 上開個 Bucket 用來存照片
- Bucket 開在哪個 Region 要記得,後面的 Cognito 設定需要
- Bucket 不用特別開成 Public,之後上傳 Image 時 ACL 設定成 public-read 就可以了。
- 常忘記的是,如果要透過 Frontend 上傳到 S3,那 Bucket 的 CORS 就要記得打開。



Cognito . Identity Pools
Cognito 下有兩個服務,User Pools 和 Identity Pools,在這裡我們只需要用到 Identity Pools 就能提供 Frontend 不需要先註冊就能上傳照片的功能。
- 記得 Region 要選和 S3 Bucket 一樣的
- 因為沒有要實作 Frontend 註冊的部分,所以選 Enable access to Unauthenticated Identities 就好。
- 建立一個新的 Identity Pool 後 AWS 會自動幫我們新建 2 個 IAM Role,一個給 Authenticated Identity,一個給 Unauthenticated Identity 用。
- 後面我們還會需要再去調整 Unauthenticated Identity 的 IAM Role。
- 最後,得到一個用來設定 AWS SDK 的 IdentityPoolId。



IAM
因為 Cognito 幫我們建的 IAM Role 並沒有預設能 Access S3 的 Permission Policy,所以最後要再去調整一下。
- IAM 並沒有分 Region 喔
- 把可以 Access S3 的 Policy 加進 Role 裡


到這邊 AWS 的設定就完成啦!
接下來就是 Frontend 的部分。
Frontend Getting Started
AWS Javascript SDK
在使用 SDK 上傳照片到 S3 之前,需要先把 AWS 的 Region、Credential,和 S3 Bucket 設定好。
// Add AWS SDK package
yarn add aws-sdk// index.js
import AWS from 'aws-sdk'AWS.config.region = AWSRegion;
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId,
});let s3 = new AWS.S3({
apiVersion: '2006-03-01',
params: { Bucket: bucketName },
});
<input type=”file”> and s3.upload()
透過 type 為 file 的 input 的 onChange event,我們可以拿到使用者上傳的照片 file,接著再透過 s3.upload() 就能上傳照片了到 S3 了。
<input
type="file"
onChange={e => {
const file = e.target.files[0];
const params = {
Key: `${new Date().toISOString()}.jpg`,
Body: file,
ACL: 'public-read',
ContentType: 'image/jpeg'
};
s3.upload(params, (err, data) => {
const { Location: imageURL } = data;
})
}}
/>這樣子,上傳照片的功能就算實作成功了!
順帶一提,選舉看板裡的上傳照片就是透過這篇的方式實作的。
