AWS SDK を使用して Object Storage Service (OSS) にアクセスするには、OSS の エンドポイント と アクセス認証情報 を設定します。その他のコード変更は不要です。
エンドポイント:S3 互換のエンドポイント形式を使用します。
{region}をcn-hangzhouなどのリージョン ID に置き換えます。リージョンの一覧については、「リージョンとエンドポイント」をご参照ください。タイプ
フォーマット
パブリックエンドポイント
https://s3.oss-{region}.aliyuncs.com内部エンドポイント
https://s3.oss-{region}-internal.aliyuncs.com転送アクセラレーションエンドポイント
https://s3.oss-accelerate.aliyuncs.com重要コンプライアンスとセキュリティを向上させるための ポリシーの変更 に伴い、2025 年 3 月 20 日以降、新規 OSS ユーザーが中国本土リージョンにある OSS バケットでデータ API オペレーションを実行するには、カスタムドメイン名を使用する必要があります (CNAME)。 デフォルトのパブリックエンドポイントは、これらの操作では使用が制限されます。 影響を受ける操作の完全なリストについては、公式発表をご参照ください。 HTTPS 経由でデータにアクセスする場合、カスタムドメインに 有効な SSL 証明書をバインドする必要があります。 コンソールでは HTTPS が適用されるため、これは OSS コンソールへのアクセスには必須です。
アクセス認証情報:Resource Access Management (RAM) で OSS 権限を持つ AccessKey を作成します。
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();SDK 1.x では、getObject によって返される S3ObjectInputStream は、close() を呼び出すと、未読のデータを直ちに破棄します。閉じる前にストリームを完全に読み取る必要があります。
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++
SDK バージョン 1.7.68 以降が必要です。
#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);ブラウザ
フロントエンド Web アプリケーションでは、STS 一時認証情報を使用する必要があります。クライアント側コードに永続的な AccessKey をハードコーディングしないでください。ご利用のサーバーが AssumeRole を呼び出して一時認証情報を取得し、クライアントに返します。完全なチュートリアルについては、「STS 一時認証情報を使用した OSS へのアクセス」をご参照ください。
import { S3Client } from '@aws-sdk/client-s3';
// Fetch an STS temporary credential from your server.
// サーバーから STS 一時認証情報をフェッチします。
async function getSTSCredentials() {
const response = await fetch('https://your-server.com/api/sts-token');
return await response.json();
}
// Initialize the S3 client with the temporary credential.
// 一時認証情報で S3 クライアントを初期化します。
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
Android アプリケーションでは、STS 一時認証情報を使用する必要があります。クライアントアプリケーションに永続的な AccessKey をハードコーディングしないでください。ご利用のサーバーが AssumeRole を呼び出して一時認証情報を取得し、クライアントに返します。完全なチュートリアルについては、「STS 一時認証情報を使用した 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;
// Implement a credentials provider that fetches an STS temporary credential from your server.
// サーバーから STS 一時認証情報をフェッチする認証情報プロバイダーを実装します。
public class OSSCredentialsProvider implements AWSCredentialsProvider {
@Override
public AWSCredentials getCredentials() {
// Fetch an STS temporary credential from your server,
// for example, by sending a request to https://your-server.com/api/sts-token.
// サーバーから STS 一時認証情報をフェッチします。
// 例: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 the credential.
// 認証情報を更新します。
}
}
// Create the S3 client.
// S3 クライアントを作成します。
AmazonS3 s3Client = AmazonS3Client.builder()
.withCredentials(new OSSCredentialsProvider())
.withEndpointConfiguration(new EndpointConfiguration(
"https://s3.oss-cn-hangzhou.aliyuncs.com", ""))
.build();
// Application code
// アプリケーションコード
s3Client.putObject("my-bucket", "test.txt", "Hello OSS");iOS
iOS アプリケーションでは、STS 一時認証情報を使用する必要があります。クライアントアプリケーションに永続的な AccessKey をハードコーディングしないでください。ご利用のサーバーが AssumeRole を呼び出して一時認証情報を取得し、クライアントに返します。完全なチュートリアルについては、「STS 一時認証情報を使用した OSS へのアクセス」をご参照ください。
#import <AWSS3/AWSS3.h>
// Implement the credentials provider.
// 認証情報プロバイダーを実装します。
@interface OSSCredentialsProvider : NSObject <AWSCredentialsProvider>
@end
@implementation OSSCredentialsProvider
- (AWSTask<AWSCredentials *> *)credentials {
return [[AWSTask taskWithResult:nil] continueWithBlock:^id(AWSTask *task) {
// Fetch an STS temporary credential from your server.
// サーバーから STS 一時認証情報をフェッチします。
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
// Configure the S3 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"];
// Application code
// アプリケーションコード
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(@"Success");
}
return nil;
}];よくある質問
アップロードの失敗:InvalidArgument: aws-chunked encoding is not supported
現象:ファイルをアップロードすると、次のエラーが表示されます。
InvalidArgument: aws-chunked encoding is not supported with the specified x-amz-content-sha256 value根本原因:
これは、AWS SDK を使用して OSS にアクセスする際に最もよくある問題です。OSS は AWS 署名バージョン 4 アルゴリズムをサポートしていますが、転送エンコーディングが異なります。
AWS S3:デフォルトでチャンクエンコーディングを使用して大きなファイルを転送します。
OSS:転送にチャンクエンコーディングをサポートしていません。
原因分析:
一部の SDK は、署名バージョン 4 の実装をチャンクエンコーディングにバインドしています。
Python (boto3):署名バージョン 4 の実装はチャンクエンコーディングの使用を強制し、無効にすることはできません。署名バージョン 2 を使用する必要があります。
Java:設定でチャンクエンコーディングを無効にできます。
Go/Node.js:デフォルトではチャンクエンコーディングは使用されないため、特別な処理は必要ありません。
ソリューション (SDK 別):
SDK | ソリューション | 理由 |
Python (boto3) | 署名バージョン 2 を使用: | boto3 の署名バージョン 4 の実装はチャンクエンコーディングにバインドされており、無効にできません。 |
Java 1.x | 署名バージョン 4 + | チャンクエンコーディングは無効にできます。 |
Java 2.x | 署名バージョン 4 + | チャンクエンコーディングは無効にできます。 |
Go v1 | 署名バージョン 4 | デフォルトではチャンクエンコーディングを使用しません。 |
Go v2 | 署名バージョン 4。ただし、Manager API は大きなファイルのアップロードにチャンクエンコーディングを使用する場合があります。 | Manager 機能はチャンクエンコーディングを使用する場合があります。 |
Node.js v3 | 署名バージョン 4 | デフォルトではチャンクエンコーディングを使用しません。 |
Python の例 (修正前と修正後):
# Incorrect configuration (boto3 Signature V4 implementation uses chunked encoding)
# 不正な設定 (boto3 の署名バージョン 4 の実装はチャンクエンコーディングを使用します)
s3 = boto3.client('s3',
endpoint_url='https://oss-cn-hongkong.aliyuncs.com',
config=Config(signature_version='v4'))
# Correct configuration (boto3 uses Signature V2)
# 正しい設定 (boto3 は署名バージョン 2 を使用します)
s3 = boto3.client('s3',
endpoint_url='https://oss-cn-hongkong.aliyuncs.com',
config=Config(signature_version='s3')) # Signature V2 is the stable solution for boto3. (署名バージョン 2 は boto3 のための安定したソリューションです。)技術的な詳細:
OSS 署名バージョン 4 は AWS 署名バージョン 4 の仕様に準拠していますが、以下の要件があります。
リクエストヘッダーに
x-oss-content-sha256: UNSIGNED-PAYLOADを含める必要があります。Transfer-Encoding: chunkedメソッドを使用してはなりません。
ほとんどの SDK は互換性のために設定できます。ただし、boto3 の署名バージョン 4 の実装はチャンクエンコーディングと密接に結合しているため、boto3 では署名バージョン 2 を使用する必要があります。
SDK と署名バージョンの選択
バージョン選択ガイド:
言語 | SDK バージョン | 署名バージョン | 主な考慮事項 |
Python | 最新の boto3 | V2 ( | boto3 の V4 実装は OSS と互換性がありません。 |
Java 1.x | 最新の 1.x バージョン | V4 | チャンクエンコーディングを無効にする必要があります。 |
Java 2.x | 最新の 2.x バージョン | V4 | チャンクエンコーディングを無効にする必要があります。 |
Node.js | v3 | V4 (デフォルト) | - |
Go v1 | 最新の v1 バージョン | V4 (デフォルト) | - |
Go v2 | 最新の v2 バージョン | V4 (デフォルト) | Manager API は大きなファイルのアップロードにチャンクエンコーディングを使用する場合があります。 |
署名バージョンの詳細:
OSS 署名バージョン 4:OSS は AWS 署名バージョン 4 アルゴリズムを完全にサポートしています。
署名バージョン 2:これは boto3 の特殊なケースであり、SDK の実装上の制限により必要となります。
互換性:boto3 を除き、他のすべての SDK は署名バージョン 4 を使用して OSS にアクセスできます。
新規プロジェクトのバージョン選択ガイド:
シナリオ | 推奨ソリューション | 理由 |
新規 Python プロジェクト | boto3 + 署名バージョン 2 | boto3 は OSS の署名バージョン 4 をサポートしていません。 |
新規 Java プロジェクト | Java 2.x + 署名バージョン 4 | パフォーマンスが向上します。 |
新規 Node.js プロジェクト | v3 + 署名バージョン 4 | - |
新規 Go プロジェクト | Go v1 + 署名バージョン 4 | 推奨 |
既存プロジェクトの移行 | 現在の SDK バージョンを維持します。 | 破壊的変更のリスクを最小限に抑えます。 |
署名エラー:SignatureDoesNotMatch
SignatureDoesNotMatch エラーが発生することがあります。これは、サーバーによって計算された署名がクライアントの署名と一致しないことを示します。
最も一般的な原因は、OSS AccessKey の代わりに AWS AccessKey を使用することです。AWS のアクセス認証情報と OSS のアクセス認証情報は別々のシステムであり、互換性はありません。コード内の aws_access_key_id や aws_secret_access_key などのパラメーターを確認し、OSS コンソールで作成した AccessKey ID と AccessKey Secret を使用していることを確認してください。
2 番目に多い原因は、クロックのずれです。S3 署名アルゴリズムは、署名にタイムスタンプを含みます。タイムスタンプがサーバーの時刻と 15 分以上異なると、OSS はリクエストを拒否します。date -u コマンドを実行して、サーバーの UTC 時刻を確認できます。時刻が不正確な場合は、ntpdate またはシステムの時刻同期サービスを使用して修正してください。
3 番目の原因は、不正なエンドポイント設定です。エンドポイントがまだ s3.amazonaws.com などの AWS ドメインを指している場合や、間違った OSS リージョンを使用している場合、署名計算は失敗します。OSS エンドポイントの標準形式は https://oss-{region}.aliyuncs.com であり、{region} は oss-cn-hangzhou や oss-cn-beijing など、バケットのリージョンと一致する必要があります。
boto3 を使用する場合、別の特定の原因があります。signature_version='s3' が設定されていない場合、boto3 はデフォルトで署名バージョン 4 を使用するため、署名が失敗します。正しい boto3 の設定には、Config(signature_version='s3') パラメーターが含まれます。
設定を確認する簡単な方法は、ossutil コマンドラインツールを使用することです。ossutil ls oss://your-bucket --access-key-id <key> --access-key-secret <secret> --endpoint oss-cn-hangzhou.aliyuncs.com を実行します。このコマンドでバケットの内容が正常にリスト表示されれば、アクセス認証情報とエンドポイントは正しく、問題はコードの設定にあることを示しています。
バケットアクセスエラー
NoSuchBucket または AccessDenied エラーは、指定されたバケットにアクセスできないことを示します。最も一般的な原因は、エンドポイントとバケットのリージョンの不一致です。
各 OSS バケットは、cn-hangzhou や cn-beijing などの特定のリージョンに属します。バケットにアクセスする際、エンドポイントはバケットが配置されているリージョンと一致する必要があります。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントは oss-cn-hangzhou.aliyuncs.com である必要があります。中国 (北京) リージョンのエンドポイントである oss-cn-beijing.aliyuncs.com は使用できません。AWS S3 とは異なり、OSS はクロスリージョンアクセスや自動リダイレクトをサポートしていません。間違ったエンドポイントを使用すると、OSS は NoSuchBucket エラーを返します。
2 番目の原因は、不正な RAM 権限です。OSS AccessKey に関連付けられた RAM ユーザーが、ターゲットバケットにアクセスする権限を持っていることを確認してください。RAM コンソールで、ユーザーに oss:ListObjects、oss:GetObject、oss:PutObject などの必要な権限が付与されていることを確認します。
3 番目の原因は、バケットの命名規則です。OSS は、仮想ホスト形式 (bucket-name.oss-cn-hangzhou.aliyuncs.com) とパス形式 (oss-cn-hangzhou.aliyuncs.com/bucket-name) の 2 つの URL スタイルをサポートしています。仮想ホスト形式を使用する場合、バケット名は DNS 命名規則に準拠する必要があり、アンダースコアを含めることはできません。バケット名にアンダースコアが含まれている場合は、SDK をパス形式アクセスを使用するように設定するか、準拠した名前で新しいバケットを作成する必要があります。
パフォーマンスの最適化
大きなファイルのアップロードとダウンロードは、オブジェクトストレージにおける共通のタスクです。AWS SDK は、OSS でも機能するいくつかの転送アクセラレーション機能を提供します。
Python boto3 を使用する場合、TransferConfig を使用してマルチパートアップロードのパラメーターを設定できます。ファイルが設定されたしきい値よりも大きい場合、boto3 は自動的にファイルをパーツに分割し、並行してアップロードするため、スループットが大幅に向上します。multipart_threshold パラメーターはマルチパートアップロードを有効にするファイルサイズのしきい値を制御し、max_concurrency は同時アップロードスレッドの数を制御し、multipart_chunksize は各パーツのサイズを制御します。これらのパラメーターを適切に設定すると、100 MB を超えるファイルのアップロード速度が数倍に向上する可能性があります。
Java SDK を使用する場合、TransferManager クラスは、マルチパートアップロード、同時転送、自動リトライなどの機能をカプセル化します。TransferManager はファイルサイズに基づいて最適な転送戦略を自動的に選択するため、パーツのロジックを手動で管理する必要はありません。
Go SDK を使用する場合、PutObject を直接使用する代わりに s3manager.Uploader を使用します。Uploader は同時マルチパートアップロードを提供し、大きなファイルを自動的に分割し、失敗したアップロードをリトライします。
Node.js SDK を使用する場合、@aws-sdk/lib-storage パッケージの Upload クラスを使用できます。このクラスはストリーミングアップロードをサポートしており、ファイルの読み取り中にアップロードを開始できるため、メモリ使用量が削減されます。
これらの転送アクセラレーション機能はすべて S3 マルチパートアップロード API に基づいており、OSS はこれを完全にサポートしています。したがって、これらを OSS で直接使用できます。