すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:署名付き URL を使用してオブジェクトをダウンロードする

最終更新日:Apr 07, 2025

デフォルトでは、Object Storage Service(OSS)バケット内のオブジェクトのアクセス制御リスト(ACL)は非公開です。オブジェクト所有者のみがオブジェクトにアクセスする権限を持っています。 OSS SDK for Python を使用して、HTTP GET リクエストを許可し、有効期間を持つ署名付き URL を生成し、その署名付き URL をユーザーと共有することで、ユーザーが一時的にオブジェクトをダウンロードできるようにすることができます。有効期間内であれば、ユーザーはオブジェクトを繰り返しダウンロードできます。有効期間が終了すると、ユーザーは新しい署名付き URL を取得する必要があります。

注意事項

  • このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用しています。 OSS と同じリージョン内の他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用します。 OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。

  • このトピックでは、環境変数からアクセス認証情報を取得しています。アクセス認証情報を設定する方法の詳細については、「アクセス認証情報を設定する」をご参照ください。

  • このトピックでは、OSS エンドポイントを使用して OSSClient インスタンスを作成しています。カスタムドメイン名または Security Token Service(STS)を使用して OSSClient インスタンスを作成する場合は、「初期化」をご参照ください。

  • 署名付き URL の生成に特定の権限は必要ありません。ただし、署名付き URL を使用してサードパーティユーザーがオブジェクトをダウンロードするには、URL の作成者が oss:GetObject 権限を持っている必要があります。詳細については、「RAM ユーザーにカスタムポリシーをアタッチする」をご参照ください。

  • このトピックでは、有効期間が 7 日間の V4 署名付き URL を使用しています。詳細については、「(推奨) URL に V4 署名を含める」をご参照ください。

プロセス

次の図は、署名付き URL を使用してオブジェクトをダウンロードする方法を示しています。

image

サンプルコード

  1. 次のコードは、HTTP GET リクエストを許可する署名付き URL を生成する方法の例を示しています。

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    
    # 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
    auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
    
    # バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
    endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
    
    # エンドポイントにマップするリージョンの ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
    region = "cn-hangzhou"
    
    # バケットの名前を指定します。
    bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
    
    # オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。例: exampledir/exampleobject.txt。
    object_name = 'exampledir/exampleobject.txt'
    
    # オブジェクトのダウンロードに使用する署名付き URL を生成します。この例では、URL の有効期間は 600 秒です。
    # デフォルトでは、OSS は署名プロセスでオブジェクトの完全なパスにあるスラッシュ (/) をエスケープ文字として認識します。したがって、署名付き URL は直接使用できません。
    # slash_safe パラメーターを True に設定します。これにより、OSS はオブジェクトの完全なパスにあるスラッシュ (/) をエスケープ文字として認識せず、署名付き URL を直接使用できます。
    url = bucket.sign_url('GET', object_name, 600, slash_safe=True)
    print('Presigned URL:', url)
  2. 次のコードは、HTTP GET リクエストを許可する署名付き URL を使用してオブジェクトをダウンロードする方法の例を示しています。

    curl

    curl -SO "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"

    Java

    import java.io.BufferedInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class Demo {
        public static void main(String[] args) {
            // HTTP GET リクエストを許可する署名付き URL を指定します。
            String fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
            // ダウンロードしたオブジェクトを保存するパスを、オブジェクト名と拡張子を含めて指定します。
            String savePath = "C:/downloads/myfile.txt";
    
            try {
                downloadFile(fileURL, savePath);
                System.out.println("ダウンロードが完了しました!");
            } catch (IOException e) {
                System.err.println("ダウンロード中にエラーが発生しました: " + e.getMessage());
            }
        }
    
        private static void downloadFile(String fileURL, String savePath) throws IOException {
            URL url = new URL(fileURL);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setRequestMethod("GET");
    
            // レスポンスコードを指定します。
            int responseCode = httpConn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                // 入力ストリームを設定します。
                InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
                // 出力ストリームを設定します。
                FileOutputStream outputStream = new FileOutputStream(savePath);
    
                byte[] buffer=new byte[4096]; // バッファのサイズを指定します。
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
    
                outputStream.close();
                inputStream.close();
            } else {
                System.out.println("ダウンロードするファイルがありません。サーバーは HTTP コードを返信しました: " + responseCode);
            }
            httpConn.disconnect();
        }
    }

    Node.js

    const https = require('https');
    const fs = require('fs');
    
    const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
    const savePath = "C:/downloads/myfile.txt";
    
    https.get(fileURL, (response) => {
        if (response.statusCode === 200) {
            const fileStream = fs.createWriteStream(savePath);
            response.pipe(fileStream);
            
            fileStream.on('finish', () => {
                fileStream.close();
                console.log("ダウンロードが完了しました!");
            });
        } else {
            console.error(`ダウンロードに失敗しました。サーバーはコードで応答しました: ${response.statusCode}`);
        }
    }).on('error', (err) => {
        console.error("ダウンロード中にエラーが発生しました:", err.message);
    });

    Python

    import requests
    
    file_url = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"
    save_path = "C:/downloads/myfile.txt"
    
    try:
        response = requests.get(file_url, stream=True)
        if response.status_code == 200:
            with open(save_path, 'wb') as f:
                for chunk in response.iter_content(4096):
                    f.write(chunk)
            print("ダウンロードが完了しました!")
        else:
            print(f"ダウンロードするファイルがありません。サーバーは HTTP コードを返信しました: {response.status_code}")
    except Exception as e:
        print("ダウンロード中にエラーが発生しました:", e)

    Go

    package main
    
    import (
        "io"
        "net/http"
        "os"
    )
    
    func main() {
        fileURL := "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"
        savePath := "C:/downloads/myfile.txt"
    
        response, err := http.Get(fileURL)
        if err != nil {
            panic(err)
        }
        defer response.Body.Close()
    
        if response.StatusCode == http.StatusOK {
            outFile, err := os.Create(savePath)
            if err != nil {
                panic(err)
            }
            defer outFile.Close()
    
            _, err = io.Copy(outFile, response.Body)
            if err != nil {
                panic(err)
            }
            println("ダウンロードが完了しました!")
        } else {
            println("ダウンロードするファイルがありません。サーバーは HTTP コードを返信しました:", response.StatusCode)
        }
    }

    JavaScript

    const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
    const savePath = "C:/downloads/myfile.txt"; // ダウンロードしたオブジェクトの名前を指定します。
    
    fetch(fileURL)
        .then(response => {
            if (!response.ok) {
                throw new Error(`サーバーは HTTP コードを返信しました: ${response.status}`);
            }
            return response.blob(); // レスポンスのタイプを blob に変更します。
        })
        .then(blob => {
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download=savePath; // ダウンロードしたオブジェクトの名前を指定します。
            document.body.appendChild(link); // この手順により、リンクがドキュメントに存在することが保証されます。
            link.click(); // リンクをクリックしてダウンロードをシミュレートします。
            link.remove(); // オブジェクトのダウンロード後、リンクを削除します。
            console.log("ダウンロードが完了しました!");
        })
        .catch(error => {
            console.error("ダウンロード中にエラーが発生しました:", error);
        });

    Android-Java

    import android.os.AsyncTask;
    import android.os.Environment;
    import java.io.BufferedInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class DownloadTask extends AsyncTask<String, String, String> {
        @Override
        protected String doInBackground(String... params) {
            String fileURL = params[0];
            String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/myfile.txt"; // ダウンロードしたオブジェクトを保存するパスを指定します。
            try {
                URL url = new URL(fileURL);
                HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setRequestMethod("GET");
                int responseCode = httpConn.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
                    FileOutputStream outputStream = new FileOutputStream(savePath);
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    outputStream.close();
                    inputStream.close();
                    return "ダウンロードが完了しました!";
                } else {
                    return "ダウンロードするファイルがありません。サーバーは HTTP コードを返信しました: " + responseCode;
                }
            } catch (Exception e) {
                return "ダウンロード中にエラーが発生しました: " + e.getMessage();
            }
        }
    }

    Objective-C

    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // 署名付き URL とオブジェクトを保存するパスを指定します。
            NSString *fileURL = @"https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
            NSString *savePath = @"/Users/your_username/Desktop/myfile.txt"; // your_username を実際のユーザー名に置き換えます。
            
            // URL オブジェクトを作成します。
            NSURL *url = [NSURL URLWithString:fileURL];
            
            // オブジェクトダウンロードタスクを作成します。
            NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                // エラーを処理します。
                if (error) {
                    NSLog(@"ダウンロード中にエラーが発生しました: %@", error.localizedDescription);
                    return;
                }
                
                // オブジェクトのデータを確認します。
                if (!data) {
                    NSLog(@"データを受信しませんでした。");
                    return;
                }
                
                // オブジェクトを保存します。
                NSError *writeError = nil;
                BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath] options:NSDataWritingAtomic error:&writeError];
                if (success) {
                    NSLog(@"ダウンロードが完了しました!");
                } else {
                    NSLog(@"ファイルの保存中にエラーが発生しました: %@", writeError.localizedDescription);
                }
            }];
            
            // オブジェクトダウンロードタスクを開始します。
            [task resume];
            
            // メインスレッドを実行し続け、非同期リクエストを完了します。
            [[NSRunLoop currentRunLoop] run];
        }
        return 0;
    }

その他のシナリオ

特定のバージョンのオブジェクトに対する HTTP GET リクエストを許可する署名付き URL を生成する

次のサンプルコードは、特定のバージョンのオブジェクトに対する HTTP GET リクエストを許可する署名付き URL を生成する方法の例を示しています。

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
import requests

# 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"

# エンドポイントにマップするリージョンの ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
region = "cn-hangzhou"

# バケットの名前を指定します。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)

# オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。例: exampledir/exampleobject.txt。
object_name = 'exampledir/exampleobject.txt'

# リクエストヘッダーを指定します。
headers = dict()
# オブジェクトのバージョン ID を指定します。
headers["versionId"] = "CAEQARiBgID8rumR2hYiIGUyOTAyZGY2MzU5MjQ5ZjlhYzQzZjNlYTAyZDE3****"

# 署名付き URL を生成し、署名付き URL の有効期間を 600 秒に設定します。
# デフォルトでは、OSS は署名プロセスでオブジェクトの完全なパスにあるスラッシュ (/) をエスケープ文字として認識します。したがって、署名付き URL は直接使用できません。
# slash_safe パラメーターを True に設定します。これにより、OSS はオブジェクトの完全なパスにあるスラッシュ (/) をエスケープ文字として認識せず、署名付き URL を直接使用できます。
url = bucket.sign_url('PUT', object_name, 600, slash_safe=True, headers=headers)
print('Presigned URL:', url)

特定のリクエストヘッダーを含む署名付き URL を使用してオブジェクトをダウンロードする

HTTP GET リクエストを許可する署名付き URL を生成するときにリクエストヘッダーを指定する場合は、署名付き URL を使用して開始された GET リクエストにリクエストヘッダーが含まれていることを確認してください。これにより、リクエストの失敗と署名エラーを防ぐことができます。

  1. 特定のリクエストヘッダーを含み、HTTP GET リクエストを許可する署名付き URL を生成します。

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    
    # 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
    auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
    
    # バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
    endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
    
    # エンドポイントにマップするリージョンの ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
    region = "cn-hangzhou"
    
    # バケットの名前を指定します。
    bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
    
    # オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。例: exampledir/exampleobject.txt。
    object_name = 'exampledir/exampleobject.txt'
    
    # リクエストヘッダーを指定します。
    headers = dict()
    # Content-Type ヘッダーを指定します。
    headers['Content-Type'] = 'text/plain; charset=utf8'
    
    # HTTP クエリパラメーターを指定します。
    params = dict()
    # 単一接続の帯域幅調整を設定します。単位: bit/s。この例では、調整のしきい値は 100 KB/s に設定されています。
    # params['x-oss-traffic-limit'] = str(100 * 1024 * 8)
    # IP アドレスまたは CIDR ブロックを指定します。
    # params['x-oss-ac-source-ip'] = "127.0.0.1"
    # サブネットマスクの数字 1 の数を指定します。
    # params['x-oss-ac-subnet-mask'] = "32"
    # VPC の ID を指定します。
    # params['x-oss-ac-vpc-id'] = "vpc-t4nlw426y44rd3iq4xxxx"
    # リクエストの転送を許可するかどうかを指定します。
    # params['x-oss-ac-forward-allow'] = "true"
    
    # オブジェクトのダウンロードに使用する署名付き URL を生成します。この例では、URL の有効期間は 600 秒です。
    # デフォルトでは、OSS は署名プロセスでオブジェクトの完全なパスにあるスラッシュ (/) をエスケープ文字として認識します。したがって、署名付き URL は直接使用できません。
    # slash_safe パラメーターを True に設定します。これにより、OSS はオブジェクトの完全なパスにあるスラッシュ (/) をエスケープ文字として認識せず、署名付き URL を直接使用できます。
    url = bucket.sign_url('GET', object_name, 600, slash_safe=True, headers=headers, params=params)
    print('Presigned URL:', url)
  2. 署名付き URL を使用し、リクエストでリクエストヘッダーを指定してオブジェクトをダウンロードします。

    curl -X GET "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241113T093321Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=f1746f121783eed5dab2d665da95fbca08505263e27476a46f88dbe3702af8a9***************************************" \
    -H "Content-Type: text/plain" \
    -o "myfile.txt"
    import requests
    
    def download_file(signed_url, file_path, headers=None, metadata=None):
        """
        署名付き URL を使用してオブジェクトをダウンロードします。
    
        :param signed_url: 署名付き URL
        :param file_path: ダウンロードするオブジェクトの完全なパス
        :param headers: リクエストヘッダー。このパラメーターはオプションです。
        :param metadata: ユーザーメタデータ。このパラメーターはオプションです。
        :return: なし
        """
        if not headers:
            headers = {}
    
        try:
            response = requests.get(signed_url, headers=headers, stream=True)
            print(f"ダウンロードステータスコード:{response.status_code}")
    
            if response.status_code == 200:
                with open(file_path, 'wb') as file:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:  # キープアライブの新しいチャンクを除外します
                            file.write(chunk)
                print("オブジェクトがダウンロードされました")
            else:
                print("ダウンロードに失敗しました")
                print(response.text)
        except Exception as e:
            print(f"エラーが発生しました:{e}")
    
    if __name__ == "__main__":
        # <signedUrl> を生成された署名付き URL に置き換えます。
        signed_url = "<signedUrl>"
        file_path = "/Users/yourLocalPath>/Downloads/downloadedFile.txt" // オブジェクトを保存するローカルパスを指定します。
    
        headers = {
            "Content-Type": "text/plain; charset=utf-8",
            # その他の必要なヘッダー
        }
    
        download_file(signed_url, file_path, headers=headers)

カスタムドメイン名を使用して署名付き URL を生成するカスタムドメイン名を使用した URL

次のコードは、カスタムドメイン名を使用して署名付き URL を生成する方法の例を示しています。

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# エンドポイントにマップするリージョンの ID を指定します。例: cn-hangzhou。署名アルゴリズム V4 を使用する場合は、このパラメーターが必要です。
region = "cn-hangzhou"

# カスタムドメイン名を指定します。例: static.example.com。
endpoint = 'http://static.example.com'

# バケットの名前を指定します。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region, is_cname=True)


# オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。例: exampledir/exampleobject.txt。
object_name = 'exampledir/exampleobject.txt'

# オブジェクトのダウンロードに使用する署名付き URL を生成します。この例では、URL の有効期間は 600 秒です。
# デフォルトでは、OSS は署名プロセスでオブジェクトの完全なパスにあるスラッシュ (/) をエスケープ文字として認識します。したがって、署名付き URL は直接使用できません。
# slash_safe パラメーターを True に設定します。これにより、OSS はオブジェクトの完全なパスにあるスラッシュ (/) をエスケープ文字として認識せず、署名付き URL を直接使用できます。
url = bucket.sign_url('GET', object_name, 600, slash_safe=True, params=params)
print('Presigned URL:', url)