檔案上傳 #
流程概況 #
當您操作 SPA 會參考到外部檔案時 (例如提案用圖片、影片),做法為先將檔案上傳至 AWS S3,並將檔案 URL 附加於 SPA 的物件中。
我們提供了取得擁有上傳至我們指定的 S3 Bucket 權限的 Temporary Security Credential 的 API Endpoint,您可以此 Credential 將檔案上傳至 S3 並取得物件 ETag,接著再以此 ETag 取得該物件的最終 URL,該 URL 即可用於 SPA 系統中。
檔案上傳相關的 API Endpoints URL 為 https://tw.buy.yahoo.com/api/fileUploader/。
詳細步驟 #
取得 Temporary Security Credential #
首先您需先至 Endpoint GET /api/filerUploader/v1/credentials 取得 Temporary Security Credential。
上傳物件 #
接著依您使用的程式語言至 https://aws.amazon.com/getting-started/tools-sdks/ 取得 AWS 提供的 SDK,搭配上一步取得的 Credential 將物件上傳至 AWS S3。
- Bucket:
ytw-shp-file-uploader
- Folder:
FileUploader/
- Region:
ap-northeast-1
新版的 AWS SDK 會視情況需要 Region 的參數
在上傳物件的同時,請於 Request Header 加入以下兩個欄位
Header Name | Type | Value |
---|---|---|
x-amz-server-side-encryption | String | 固定為 AES256 |
x-amz-meta-YahooWSSID-Authorization | String | 由 Endpoint GET v1/token 取得的 WSSID |
若您使用的是官方的 SDK,請注意指定custom user-metadata
是否會自動加上前綴x-amz-meta-
,若是,則需注意應只輸入YahooWSSID-Authorization
。
成功上傳後,您可由結果取得該物件的 ETag
。
Java 範例程式
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.PutObjectResult;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class Sample {
public String uploadAndGetETag() throws Exception {
// WSSID for authorization, obtained from Endpoint GET v1/token
// ref: https://tw.supplier.yahoo.com/docs/sp/api/endpoints/common/#get-v1token
String wssid = "ABCDEFabcdef0123456789._-~";
// Temporary Security Credential from Endpoint GET /api/filerUploader/v1/credentials
// ref: https://tw.supplier.yahoo.com/docs/sp/api/file_upload/endpoints/#get-v1credentials
String credentialId = "ABCDE12345";
String credentialKey = "ABCDEF/abcdef/123456=";
String credentialToken = "ABCDEFG/abcdefg/1234567===";
// Create an S3 client with the provided credentials
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard();
builder.withRegion(Regions.AP_NORTHEAST_1);
builder.withCredentials(new AWSStaticCredentialsProvider(
new BasicSessionCredentials(
credentialId, credentialKey, credentialToken
)
));
AmazonS3 s3 = builder.build();
// Prepare metadata for the S3 object
Map<String, String> userMetadata = new HashMap<>();
userMetadata.put("YahooWSSID-Authorization", wssid);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
metadata.setUserMetadata(userMetadata);
// Set the content length (optional, but recommended)
String filePath = "test.png";
File file = new File(filePath);
metadata.setContentLength(file.length());
// Construct the S3 object key and upload the file
String bucketName = "ytw-shp-file-uploader";
String key = String.format("FileUploader/%s", FilenameUtils.getName(filePath));
try (InputStream inputStream = new FileInputStream(file)) {
PutObjectRequest putObjectRequest = new PutObjectRequest(
bucketName, key, inputStream, metadata
);
return s3.putObject(putObjectRequest).getETag();
}
}
}
PHP 範例程式
<?php
require_once ('vendor/autoload.php');
use Aws\Credentials\CredentialProvider;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
// WSSID for authorization, obtained from Endpoint GET v1/token
// ref: https://tw.supplier.yahoo.com/docs/sp/api/endpoints/common/#get-v1token
$wssid = 'ABCDEFabcdef0123456789._-~';
// Temporary Security Credential from Endpoint GET /api/filerUploader/v1/credentials
// ref: https://tw.supplier.yahoo.com/docs/sp/api/file_upload/endpoints/#get-v1credentials
$credentialId = 'ABCDE12345';
$credentialKey = 'ABCDEF/abcdef/123456=';
$credentialToken = 'ABCDEFG/abcdefg/1234567===';
// Create an S3 client with the provided credentials
try
{
$s3Client = new S3Client
(
array
(
'region' => 'ap-northeast-1',
'version' => 'latest',
// ref: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials_temporary.html
'credentials' => array
(
'key' => $credentialId,
'secret' => $credentialKey,
'token' => $credentialToken,
)
)
);
}
catch (S3Exception $e)
{
echo "[S3 Client Init Error] " . $e->getMessage() . "\n";
exit(1);
}
// Construct the S3 object and upload the file
$imgFile = "test.png";
try
{
// Parameter syntax ref: https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject
$result = $s3Client->putObject (
array
(
'Bucket' => 'ytw-shp-file-uploader',
'Key' => 'FileUploader/'.basename($imgFile),
'ServerSideEncryption' => 'AES256',
'SourceFile' => $imgFile,
'x-amz-server-side-encryption' => 'AES256',
'x-amz-meta-YahooWSSID-Authorization' => $wssid,
)
);
echo "ETag: " . $result['ETag'] . "\n";
}
catch (S3Exception $e)
{
echo "[Upload Error] " . $e->getMessage() . "\n";
echo "[Detailed Error XML]\n" . $e->getAwsErrorMessage() . "\n";
echo "Error Code: " . $e->getAwsErrorCode() . "\n";
echo "Status Code: " . $e->getStatusCode() . "\n";
exit(2);
}
exit;
?>
Python 範例程式
import boto3
# WSSID for authorization, obtained from Endpoint GET v1/token
# ref: https://tw.supplier.yahoo.com/docs/sp/api/endpoints/common/#get-v1token
wssid = 'ABCDEFabcdef0123456789._-~'
# Temporary Security Credential from Endpoint GET /api/filerUploader/v1/credentials
# ref: https://tw.supplier.yahoo.com/docs/sp/api/file_upload/endpoints/#get-v1credentials
aws_access_key_id = 'ABCDE12345'
aws_secret_access_key = 'ABCDEF/abcdef/123456='
aws_session_token = 'ABCDEFG/abcdefg/1234567==='
# Create an S3 client with the provided credentials
s3 = boto3.client(
's3',
region_name='ap-northeast-1',
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
aws_session_token=aws_session_token
)
# Construct the S3 object key
file_path = 'test.png'
file_name = file_path.rsplit('/', 1)[-1]
s3_key = 'FileUploader/' + file_name
# Upload the file to S3
bucket_name = 'ytw-shp-file-uploader'
with open(file_path, 'rb') as file:
response = s3.put_object(
Bucket=bucket_name,
Key=s3_key,
Body=file,
Metadata={
'YahooWSSID-Authorization': wssid
},
ServerSideEncryption='AES256'
)
# Get the ETag of the uploaded object
etag = response.get('ETag')
print(f"ETag: {etag}")
取得檔案 URL #
最後,您可以上一步取得的 ETag
詢問 Endpoint GET /api/fileUploader/v1/fileObjects 以取得其 URL,並用於 SPA 系統中。