[AWS] curl 上傳檔案至 AWS S3

在導入 AWS 作為後端雲平台的時候,遇到了需要透過 curl 指令將檔案直接上傳到 S3 的需求,一開始以為一定要透過 presigned URL 的方式才能夠進行,但是後來參考了幾篇網路的文章並且經過實作驗證之後,發現也可以直接用 bash shell 配合 AWS credentials 進行,由於 AWS 的 credentials 有分成有時效性與無時效性兩種,本篇針對兩種不同的憑證放上不同的程式碼。

使用無時效性 Credentials (AWS Key, SecretKey)

file=/path/to/file/to/upload.tar.gz
bucket=your-bucket
resource="/${bucket}/${file}"
contentType="application/x-compressed-tar"
dateValue=`date -R`
stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}"
s3Key=xxxxxxxxxxxxxxxxxxxx
s3Secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
signature=`echo -en ${stringToSign} | openssl sha1 -hmac ${s3Secret} -binary | base64`
curl -X PUT -T "${file}" \
  -H "Host: ${bucket}.s3.amazonaws.com" \
  -H "Date: ${dateValue}" \
  -H "Content-Type: ${contentType}" \
  -H "Authorization: AWS ${s3Key}:${signature}" \
  https://${bucket}.s3.amazonaws.com/${file}

使用有時效性 Credentials (AWS Key, SecretKey, SessionToken)

bucket=$1
path=$2
file=$3
aws_path=$4
date=$(date +"%a, %d %b %Y %T %z")
acl="x-amz-acl:public-read"
content_type='application/x-compressed-tar'
token="x-amz-security-token:"${S3SESSION}
string="PUT\n\n$content_type\n$date\n$acl\n$token\n/$bucket$aws_path$file"
signature=$(echo -en "${string}" | openssl sha1 -hmac "${S3SECRET}" -binary | base64)

curl -v -X PUT -T "$path/$file" \
  -H "Host: $bucket.s3.amazonaws.com" \ 
  -H "Date: $date" \
  -H "Content-Type: $content_type" \
  -H "$acl" \
  -H "$token" \
  -H "Authorization: AWS ${S3KEY}:$signature" \
  "https://$bucket.s3.amazonaws.com$aws_path$file"

備註:特別注意使用有時效性的指令,裡面有針對 S3 bucket 的 ACL 做進一步的參數調控,這部分我們之後再來詳盡說明。