全部产品
Search
文档中心

Object Storage Service:Akses OSS menggunakan AWS SDK

更新时间:Dec 31, 2025

OSS kompatibel dengan API AWS S3. Anda dapat mengakses OSS menggunakan AWS SDK tanpa mengubah kode Anda. Untuk melakukannya, konfigurasikan Endpoint dan kredensial akses OSS.

  • Endpoint: Gunakan titik akhir publik yang kompatibel dengan S3 (https://s3.oss-{region}.aliyuncs.com) atau titik akhir jaringan internal (https://s3.oss-{region}-internal.aliyuncs.com). Ganti {region} dengan ID wilayah aktual, seperti cn-hangzhou. Untuk daftar lengkap wilayah, lihat Wilayah dan titik akhir.

    Penting

    Karena adanya perubahan kebijakan untuk meningkatkan kepatuhan dan keamanan, mulai 20 Maret 2025, pengguna OSS baru harus menggunakan nama domain kustom (CNAME) untuk melakukan operasi API data pada bucket OSS yang berlokasi di wilayah Tiongkok Daratan. Titik akhir publik bawaan dibatasi untuk operasi tersebut. Lihat pengumuman resmi untuk daftar lengkap operasi yang terdampak. Jika Anda mengakses data melalui HTTPS, Anda harus mengikat Sertifikat SSL yang valid ke domain kustom Anda. Hal ini wajib untuk akses Konsol OSS, karena konsol menerapkan HTTPS.

  • Kredensial akses: Buat AccessKey dengan izin akses OSS di Resource Access Management (RAM).

Java

SDK 2.x

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Configuration;
import java.net.URI;

S3Client s3Client = S3Client.builder()
    .endpointOverride(URI.create("https://s3.oss-cn-hangzhou.aliyuncs.com"))
    .region(Region.AWS_GLOBAL)
    .serviceConfiguration(
        S3Configuration.builder()
            .pathStyleAccessEnabled(false)
            .chunkedEncodingEnabled(false)
            .build()
    )
    .build();

SDK 1.x

import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
    .withEndpointConfiguration(new EndpointConfiguration(
        "https://s3.oss-cn-hangzhou.aliyuncs.com", 
        "cn-hangzhou"))
    .withPathStyleAccessEnabled(false)
    .withChunkedEncodingDisabled(false)
    .build();

Pada SDK 1.x, memanggil close() pada S3ObjectInputStream yang dikembalikan oleh getObject akan langsung membuang data yang belum dibaca. Anda harus membaca seluruh data sebelum menutup aliran tersebut.

S3Object object = s3Client.getObject("my-bucket", "file.txt");
InputStream input = object.getObjectContent();

byte[ ] data = IOUtils.toByteArray(input);

input.close();

Python

import boto3
from botocore.config import Config

s3 = boto3.client(
    's3',
    endpoint_url='https://s3.oss-cn-hangzhou.aliyuncs.com',
    config=Config(
        signature_version='s3',
        s3={'addressing_style': 'virtual'}
    )
)

Node.js

SDK v3

import { S3Client } from '@aws-sdk/client-s3';

const client = new S3Client({
    endpoint: 'https://s3.oss-cn-hangzhou.aliyuncs.com',
    region: 'cn-hangzhou'
});

SDK v2

const AWS = require('aws-sdk');

const s3 = new AWS.S3({
    endpoint: 'https://s3.oss-cn-hangzhou.aliyuncs.com',
    region: 'cn-hangzhou'
});

Go

SDK v2

import (
    "context"
    "github.com/aws/aws-sdk-go-v2/aws"
    awsconfig "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

cfg, _ := awsconfig.LoadDefaultConfig(context.TODO(),
    awsconfig.WithEndpointResolverWithOptions(
        aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
            return aws.Endpoint{
                URL: "https://s3.oss-cn-hangzhou.aliyuncs.com",
            }, nil
        }),
    ),
)
client := s3.NewFromConfig(cfg)

SDK v1

import (
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

sess := session.Must(session.NewSessionWithOptions(session.Options{
    Config: aws.Config{
        Endpoint: aws.String("https://s3.oss-cn-hangzhou.aliyuncs.com"),
        Region:   aws.String("cn-hangzhou"),
    },
    SharedConfigState: session.SharedConfigEnable,
}))
svc := s3.New(sess)

.NET

SDK 3.x

using Amazon.S3;

var config = new AmazonS3Config
{
    ServiceURL = "https://s3.oss-cn-hangzhou.aliyuncs.com"
};
var client = new AmazonS3Client(config);

SDK 2.x

using Amazon.S3;

var config = new AmazonS3Config
{
    ServiceURL = "https://s3.oss-cn-hangzhou.aliyuncs.com"
};
var client = new AmazonS3Client(config);

PHP

SDK 3.x

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Aws\S3\S3Client;

$s3Client = new S3Client([
    'version' => '2006-03-01',
    'region'  => 'cn-hangzhou',
    'endpoint' => 'https://s3.oss-cn-hangzhou.aliyuncs.com'
]);

SDK 2.x

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Aws\S3\S3Client;

$s3Client = S3Client::factory([
    'version' => '2006-03-01',
    'region'  => 'cn-hangzhou',
    'base_url' => 'https://s3.oss-cn-hangzhou.aliyuncs.com'
]);

Ruby

SDK 3.x

require 'aws-sdk-s3'

s3 = Aws::S3::Client.new(
  endpoint: 'https://s3.oss-cn-hangzhou.aliyuncs.com',
  region: 'cn-hangzhou'
)

SDK 2.x

require 'aws-sdk'

s3 = AWS::S3::Client.new(
  s3_endpoint: 's3.oss-cn-hangzhou.aliyuncs.com',
  region: 'cn-hangzhou',
  s3_force_path_style: false
)

C++

Memerlukan versi SDK 1.7.68 atau lebih baru.

#include <aws/s3/S3Client.h>
#include <aws/core/client/ClientConfiguration.h>

Aws::Client::ClientConfiguration config;
config.endpointOverride = "s3.oss-cn-hangzhou.aliyuncs.com";
config.region = "cn-hangzhou";

Aws::S3::S3Client s3_client(config);

Browser

Aplikasi web frontend harus menggunakan kredensial temporary dari Security Token Service (STS). Jangan hard-code AccessKey permanen di sisi client. Server memanggil operasi AssumeRole untuk mendapatkan kredensial temporary dan mengirimkannya ke client. Untuk informasi selengkapnya, lihat Gunakan kredensial temporary STS untuk mengakses OSS.

import { S3Client } from '@aws-sdk/client-s3';

// Dapatkan kredensial temporary STS dari server.
async function getSTSCredentials() {
    const response = await fetch('https://your-server.com/api/sts-token');
    return await response.json();
}

// Inisialisasi client S3 dengan kredensial temporary.
const client = new S3Client({
    region: 'cn-hangzhou',
    endpoint: 'https://s3.oss-cn-hangzhou.aliyuncs.com',
    credentials: async () => {
        const creds = await getSTSCredentials();
        return {
            accessKeyId: creds.accessKeyId,
            secretAccessKey: creds.secretAccessKey,
            sessionToken: creds.securityToken,
            expiration: new Date(creds.expiration)
        };
    }
});

Android

Aplikasi seluler (Android) harus menggunakan kredensial sementara STS. Jangan hard-code AccessKey permanen di sisi klien. Server memanggil operasi AssumeRole untuk mendapatkan kredensial sementara dan mengirimkannya ke klien. Untuk informasi selengkapnya, lihat Gunakan kredensial temporary STS untuk mengakses OSS.

import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;

// Implementasikan penyedia kredensial untuk mendapatkan kredensial temporary STS dari server.
public class OSSCredentialsProvider implements AWSCredentialsProvider {
    @Override
    public AWSCredentials getCredentials() {
        // Dapatkan kredensial temporary STS dari server Anda.
        // Permintaan https://your-server.com/api/sts-token
        String accessKeyId = fetchFromServer("accessKeyId");
        String secretKeyId = fetchFromServer("secretKeyId");
        String securityToken = fetchFromServer("securityToken");
        
        return new BasicSessionCredentials(accessKeyId, secretKeyId, securityToken);
    }
    
    @Override
    public void refresh() {
        // Refresh kredensial.
    }
}

// Buat client S3.
AmazonS3 s3Client = AmazonS3Client.builder()
    .withCredentials(new OSSCredentialsProvider())
    .withEndpointConfiguration(new EndpointConfiguration(
        "https://s3.oss-cn-hangzhou.aliyuncs.com", ""))
    .build();

// Logika bisnis
s3Client.putObject("my-bucket", "test.txt", "Hello OSS");

iOS

Aplikasi mobile (iOS) harus menggunakan kredensial temporary STS. Jangan hard-code AccessKey permanen di sisi client. Server memanggil operasi AssumeRole untuk mendapatkan kredensial temporary dan mengembalikannya ke client. Untuk informasi selengkapnya, lihat Gunakan kredensial temporary STS untuk mengakses OSS.

#import <AWSS3/AWSS3.h>

// Implementasikan penyedia kredensial.
@interface OSSCredentialsProvider : NSObject <AWSCredentialsProvider>
@end

@implementation OSSCredentialsProvider

- (AWSTask<AWSCredentials *> *)credentials {
    return [[AWSTask taskWithResult:nil] continueWithBlock:^id(AWSTask *task) {
        // Dapatkan kredensial temporary STS dari server.
        NSString *accessKey = [self fetchFromServer:@"accessKeyId"];
        NSString *secretKey = [self fetchFromServer:@"secretKeyId"];
        NSString *sessionToken = [self fetchFromServer:@"securityToken"];
        
        AWSCredentials *credentials = [[AWSCredentials alloc]
            initWithAccessKey:accessKey
            secretKey:secretKey
            sessionKey:sessionToken
            expiration:[NSDate dateWithTimeIntervalSinceNow:3600]];
        
        return [AWSTask taskWithResult:credentials];
    }];
}

@end

// Konfigurasikan client S3.
AWSEndpoint *endpoint = [[AWSEndpoint alloc] initWithURLString:@"https://s3.oss-cn-hangzhou.aliyuncs.com"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc]
    initWithRegion:AWSRegionUnknown
    endpoint:endpoint
    credentialsProvider:[[OSSCredentialsProvider alloc] init]];

[AWSS3 registerS3WithConfiguration:configuration forKey:@"OSS"];
AWSS3 *s3 = [AWSS3 S3ForKey:@"OSS"];

// Logika bisnis
AWSS3PutObjectRequest *request = [AWSS3PutObjectRequest new];
request.bucket = @"my-bucket";
request.key = @"test.txt";
request.body = [@"Hello OSS" dataUsingEncoding:NSUTF8StringEncoding];

[[s3 putObject:request] continueWithBlock:^id(AWSTask *task) {
    if (task.error) {
        NSLog(@"Error: %@", task.error);
    } else {
        NSLog(@"Berhasil");
    }
    return nil;
}];

FAQ

Unggah gagal: InvalidArgument: aws-chunked encoding is not supported

Gejala: Anda menerima error berikut saat mengunggah file:

InvalidArgument: aws-chunked encoding is not supported with the specified x-amz-content-sha256 value

Akar masalah:

Ini adalah masalah paling umum yang terjadi saat Anda mengakses OSS menggunakan AWS SDK. OSS mendukung algoritma AWS Signature V4, tetapi dengan perbedaan dalam transfer encoding:

  • AWS S3 menggunakan chunked encoding secara default untuk mentransfer file besar.

  • OSS tidak mendukung transfer yang menggunakan chunked encoding.

Penyebab:

Implementasi Signature V4 di beberapa SDK bergantung pada chunked encoding:

  • Python (boto3): Signature V4 menerapkan chunked encoding, yang tidak dapat dinonaktifkan. Beralihlah ke Signature V2.

  • Java: Anda dapat menonaktifkan chunked encoding dalam konfigurasi.

  • Go/Node.js: Chunked encoding tidak digunakan secara default. Tidak diperlukan penanganan khusus.

Solusi berdasarkan SDK:

SDK

Solusi

Alasan

Python (boto3)

Gunakan Signature V2: signature_version='s3'

Implementasi Signature V4 boto3 terikat pada chunked encoding dan tidak dapat dinonaktifkan.

Java 1.x

Signature V4 + .withChunkedEncodingDisabled(true)

Chunked encoding dapat dinonaktifkan.

Java 2.x

Signature V4 + .chunkedEncodingEnabled(false)

Chunked encoding dapat dinonaktifkan.

Go v1

Signature V4

Tidak menggunakan chunked encoding secara default.

Go v2

Signature V4. Perhatikan Manager untuk unggah file besar.

Fitur Manager mungkin menggunakan chunked encoding.

Node.js v3

Signature V4

Tidak menggunakan chunked encoding secara default.

Contoh Python: Sebelum dan sesudah perbaikan:

# Konfigurasi salah (implementasi V4 boto3 menggunakan chunked encoding)
s3 = boto3.client('s3',
    endpoint_url='https://oss-cn-hongkong.aliyuncs.com',
    config=Config(signature_version='v4'))

# Konfigurasi benar (boto3 menggunakan signature V2)
s3 = boto3.client('s3',
    endpoint_url='https://oss-cn-hongkong.aliyuncs.com',
    config=Config(signature_version='s3'))  # Signature V2 adalah solusi stabil untuk boto3

Detail teknis:

Signature V4 OSS mengikuti spesifikasi AWS Signature Version 4, dengan persyaratan berikut:

  • Header permintaan mencakup x-oss-content-sha256: UNSIGNED-PAYLOAD.

  • Metode Transfer-Encoding: chunked tidak digunakan.

Sebagian besar SDK mendukung kompatibilitas melalui konfigurasi. Namun, implementasi Signature V4 boto3 sangat terikat dengan chunked encoding. Oleh karena itu, Anda harus menggunakan Signature V2 dengan boto3.

Pemilihan SDK dan versi signature

Referensi pemilihan versi:

Bahasa

Versi SDK

Signature Version

Catatan konfigurasi

Python

Versi boto3 terbaru

Signature V2 (s3)

Implementasi V4 boto3 tidak kompatibel dengan OSS.

Java 1.x

Versi 1.x terbaru

Signature V4

Chunked encoding harus dinonaktifkan.

Java 2.x

Versi 2.x terbaru

Signature V4

Chunked encoding harus dinonaktifkan.

Node.js

v3

Signature V4 (default)

-

Go v1

Versi v1 terbaru

Signature V4 (default)

-

Go v2

Versi v2 terbaru

Signature V4 (default)

Pertimbangan bagi manajer terkait unggahan file besar

Detail Versi Tanda Tangan:

  • Signature V4 OSS: OSS mendukung sepenuhnya algoritma AWS Signature V4.

  • Signature V2: Signature V2 diperlukan untuk boto3 karena keterbatasan implementasi SDK.

  • Kompatibilitas: Kecuali boto3, semua SDK lain dapat menggunakan Signature V4 untuk mengakses OSS.

Pemilihan versi untuk proyek baru:

Skenario

Solusi Opsional

Alasan

Proyek Python baru

boto3 + Signature V2

boto3 saat ini tidak mendukung V4 OSS.

Proyek Java baru

Java 2.x + Signature V4

Kinerja lebih baik.

Proyek Node.js baru

v3 + Signature V4

-

Proyek Go baru

Go v1 + Signature V4

Direkomendasikan.

Migrasi proyek yang sudah ada

Pertahankan versi SDK saat ini.

Meminimalkan risiko perubahan.

Error signature: SignatureDoesNotMatch

Anda mungkin mengalami error SignatureDoesNotMatch. Error ini menunjukkan bahwa signature yang dihitung di sisi server tidak sesuai dengan signature yang disediakan oleh client.

Penyebab paling umum adalah menggunakan AccessKey AWS, bukan AccessKey OSS, dalam kode Anda. Kredensial akses AWS dan kredensial akses OSS merupakan dua sistem terpisah dan tidak dapat saling dipertukarkan. Periksa parameter seperti aws_access_key_id dan aws_secret_access_key dalam kode Anda. Pastikan Anda menggunakan ID AccessKey dan Rahasia AccessKey yang dibuat di konsol OSS.

Penyebab kedua paling umum adalah deviasi jam server. Algoritma signature S3 menyertakan timestamp dalam signature. Sisi server OSS memverifikasi selisih antara waktu permintaan dan waktu server. Jika jam server Anda tidak sinkron dengan waktu standar lebih dari 15 menit, semua permintaan akan ditolak. Anda dapat memeriksa waktu UTC server dengan perintah date -u. Jika waktunya salah, gunakan ntpdate atau layanan sinkronisasi waktu sistem untuk memperbaikinya.

Penyebab ketiga adalah konfigurasi endpoint yang salah. Jika endpoint mengarah ke nama domain AWS, seperti s3.amazonaws.com, atau menggunakan wilayah OSS yang salah, perhitungan signature akan gagal. Format standar untuk endpoint OSS adalah https://oss-{region}.aliyuncs.com. Wilayah harus sesuai dengan wilayah tempat bucket berada, seperti oss-cn-hangzhou atau oss-cn-beijing.

Penyebab potensial lainnya khusus terjadi saat menggunakan boto3. Jika Anda tidak mengonfigurasi signature_version='s3', boto3 akan menggunakan algoritma signature V4 default, yang menyebabkan perhitungan signature gagal. Konfigurasi boto3 yang benar harus menyertakan parameter Config(signature_version='s3').

Cara sederhana untuk memverifikasi konfigurasi Anda adalah dengan menggunakan antarmuka baris perintah ossutil. Jalankan perintah berikut: ossutil ls oss://your-bucket --access-key-id <key> --access-key-secret <secret> --endpoint oss-cn-hangzhou.aliyuncs.com. Jika perintah berhasil menampilkan isi bucket, kredensial akses dan endpoint Anda sudah benar. Masalah kemungkinan besar terletak pada konfigurasi kode Anda.

Error akses bucket

Error NoSuchBucket atau AccessDenied menunjukkan bahwa bucket yang ditentukan tidak dapat diakses. Penyebab paling umum adalah ketidaksesuaian antara endpoint dan wilayah bucket.

Setiap bucket OSS termasuk dalam wilayah tertentu, seperti cn-hangzhou atau cn-beijing. Saat Anda mengakses bucket, endpoint harus sesuai dengan wilayah bucket tersebut. Misalnya, jika bucket Anda berada di wilayah Hangzhou, endpoint-nya adalah oss-cn-hangzhou.aliyuncs.com. Anda tidak dapat menggunakan endpoint wilayah Beijing oss-cn-beijing.aliyuncs.com. Berbeda dengan AWS S3 yang memungkinkan akses lintas wilayah dan melakukan pengalihan otomatis, OSS tidak mendukung akses cross-region. Menggunakan endpoint yang salah menghasilkan error NoSuchBucket.

Penyebab kedua adalah masalah pada konfigurasi izin RAM. Periksa apakah Pengguna RAM yang terkait dengan AccessKey OSS Anda memiliki izin untuk mengakses bucket target. Di halaman manajemen RAM pada konsol OSS, pastikan pengguna tersebut diberikan izin yang diperlukan, seperti oss:ListObjects, oss:GetObject, dan oss:PutObject.

Penyebab ketiga terkait dengan konvensi penamaan bucket. OSS mendukung dua gaya URL: gaya virtual host (bucket-name.oss-cn-hangzhou.aliyuncs.com) dan gaya path (oss-cn-hangzhou.aliyuncs.com/bucket-name). Saat Anda menggunakan gaya virtual host, nama bucket harus mematuhi konvensi penamaan DNS dan tidak boleh mengandung garis bawah. Jika nama bucket Anda mengandung garis bawah, Anda harus menggunakan gaya path dalam konfigurasi SDK atau membuat bucket baru dengan nama yang sesuai.

Optimalisasi kinerja

Mengunggah dan mengunduh file besar merupakan kebutuhan umum dalam aplikasi penyimpanan objek. AWS SDK menyediakan berbagai mekanisme akselerasi transfer yang juga efektif untuk OSS.

Saat menggunakan Python boto3, Anda dapat mengonfigurasi parameter unggah multi-bagian dengan TransferConfig. Ketika ukuran file melebihi ambang batas yang dikonfigurasi, boto3 secara otomatis membagi file menjadi beberapa bagian dan mengunggahnya secara konkuren. Hal ini secara signifikan meningkatkan kecepatan transfer. Parameter multipart_threshold menentukan ambang batas ukuran file untuk mengaktifkan unggah multi-bagian. max_concurrency menentukan jumlah thread unggah konkuren, dan multipart_chunksize menentukan ukuran setiap bagian. Mengonfigurasi parameter ini dengan benar dapat meningkatkan kecepatan unggah file besar di atas 100 MB hingga beberapa kali lipat.

Saat menggunakan SDK Java, kelas TransferManager menyediakan fitur seperti unggah multi-bagian, transfer konkuren, dan retry otomatis. TransferManager secara otomatis memilih strategi transfer optimal berdasarkan ukuran file, sehingga Anda tidak perlu menangani logika multi-bagian secara manual.

Saat menggunakan SDK Go, Anda harus memanggil s3manager.Uploader alih-alih PutObject secara langsung. Uploader memiliki fitur unggah multi-bagian konkuren bawaan yang secara otomatis membagi file besar untuk diunggah secara konkuren dan menangani logika retry untuk unggahan yang gagal.

Saat menggunakan SDK Node.js, Anda dapat menggunakan kelas Upload dari paket @aws-sdk/lib-storage. Kelas ini mendukung unggah streaming. Unggahan file dapat dimulai saat file sedang dibaca, sehingga mengurangi penggunaan memori. Contohnya tersedia di bagian Node.js di atas.

Semua mekanisme akselerasi transfer ini didasarkan pada API unggah multi-bagian S3. Karena OSS sepenuhnya kompatibel dengan API ini, Anda dapat menggunakan mekanisme tersebut langsung tanpa mengubah kode Anda.