Cooking Frontend . Image Uploader . Upload Image to S3 through AWS Javascript SDK

yes
yes
Sep 1, 2018 · 6 min read
PostgreSQL ?

上傳照片是軟體服務裡很常見的一種功能,做法也百百種,而利用 AWS S3 的空間和 SDK 來實作是很常見的做法,這裡我們就是要用 AWS Javascript SDK 來實作從 Browser 直接將照片上傳到 AWS S3。

在有 SDK 的情況下 Frontend 的部分並不難,但 Frontend 平常較少接觸的 AWS 部分可能就很容易忘記該怎麼設定 (ex: IAM),又或者沒跟上新的改變 (ex: Cognito),所以這篇會著重在 AWS 的設定細節。


  1. AWS Setting Up (Developer Guide)
    - S3 . Bucket
    - Cognito . Identity Pools
    - IAM
  2. 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 就要記得打開。
Create an AWS S3 Bucket
Setting CORS Configuration of S3 Bucket

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。
Create an Identity Pool
Two auto-generated IAM Roles
IdentityPoolId for setting up AWS SDKs

IAM

因為 Cognito 幫我們建的 IAM Role 並沒有預設能 Access S3 的 Permission Policy,所以最後要再去調整一下。

  • IAM 並沒有分 Region 喔
  • 把可以 Access S3 的 Policy 加進 Role 裡
The IAM Rule and it’s Permission Policies of the Unauthenticated Identity
Permission Policy for accessing AWS S3

到這邊 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;
})
}}
/>

這樣子,上傳照片的功能就算實作成功了!

順帶一提,選舉看板裡的上傳照片就是透過這篇的方式實作的。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade