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

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

最終更新日:Apr 14, 2025

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

注意事項

  • このトピックのサンプルコードでは、中国 (杭州) リージョンのリージョン ID cn-hangzhou を使用しています。 デフォルトでは、パブリックエンドポイントを使用してバケット内のリソースにアクセスします。 バケットが配置されているのと同じリージョン内の他の Alibaba Cloud サービスからバケット内のリソースにアクセスする場合は、内部エンドポイントを使用します。 OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。

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

  • 権限がなくても署名付き URL を生成できます。 ただし、oss:GetObject 権限を持っている場合にのみ、サードパーティは署名付き URL を使用してオブジェクトをダウンロードできます。 権限を付与する方法の詳細については、「RAM ユーザーにカスタム権限を付与する」をご参照ください。

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

プロセス

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

操作構文

特定の操作を呼び出して署名付き URL を生成し、署名付き URL を使用してバケット内のオブジェクトに一時的なアクセス権限を付与できます。 URL の有効期限が切れるまで、署名付き URL を複数回使用できます。

構文

func (c *Client) Presign(ctx context.Context, request any, optFns ...func(*PresignOptions)) (result *PresignResult, err error)

リクエストパラメーター

パラメーター

タイプ

説明

ctx

context.Context

リクエストのコンテキスト。

request

*GetObjectRequest

署名付き URL の生成に使用する API 操作の名前。

optFns

...func(*PresignOptions)

署名付き URL の有効期間。 このパラメーターを指定しない場合、署名付き URL はデフォルト値である 15 分を使用します。 このパラメーターはオプションです。

PressignOptions

オプション

タイプ

説明

Expires

time.Duration

署名付き URL の有効期間。 たとえば、有効期間を 30 分に設定するには、Expires を 30 * time.Minute に設定します。

Expiration

time.Time

署名付き URL の絶対有効期限。

重要

V4 署名アルゴリズムを使用する場合、有効期間は最大 7 日間です。 Expiration と Expires の両方を指定した場合、Expiration が優先されます。

レスポンスパラメーター

パラメーター

タイプ

説明

result

*PresignResult

署名付き URL、HTTP メソッド、有効期間、リクエストで指定されたリクエストヘッダーなど、返された結果。

err

error

リクエストのステータス。 リクエストが失敗した場合、err の値は nil になりません。

PresignResult のレスポンスパラメーター

パラメーター

タイプ

説明

Method

string

操作に対応する HTTP メソッド。 たとえば、GetObject 操作の HTTP メソッドは GET です。

URL

string

署名付き URL。

Expiration

time.Time

署名付き URL の有効期限。

SignedHeaders

map[string]string

リクエストで指定されたリクエストヘッダー。 たとえば、Content-Type ヘッダーの値が指定されている場合は、Content-Type に関する情報が返されます。

サンプルコード

  1. 次のサンプルコードは、オブジェクト所有者が HTTP GET リクエストを許可する署名付き URL を生成する方法の例を示しています。

    package main
    
    import (
    	"context"
    	"flag"
    	"log"
    	"time"
    
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
    )
    
    // グローバル変数を指定します。
    var (
    	region     string // バケットが配置されているリージョン。
    	bucketName string // バケットの名前。
    	objectName string // オブジェクトの名前。
    )
    
    // コマンドラインパラメーターを初期化するために使用される init 関数を指定します。
    func init() {
    	flag.StringVar(&region, "region", "", "バケットが配置されているリージョン。")
    	flag.StringVar(&bucketName, "bucket", "", "バケットの名前。")
    	flag.StringVar(&objectName, "object", "", "オブジェクトの名前。")
    }
    
    func main() {
    	// コマンドラインパラメーターを解析します。
    	flag.Parse()
    
    	// バケット名が空かどうかを確認します。
    	if len(bucketName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("無効なパラメーター、バケット名が必要です")
    	}
    
    	// リージョンが空かどうかを確認します。
    	if len(region) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("無効なパラメーター、リージョンが必要です")
    	}
    
    	// オブジェクト名が空かどうかを確認します。
    	if len(objectName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("無効なパラメーター、オブジェクト名が必要です")
    	}
    
    	// デフォルトの構成を読み込み、認証情報プロバイダーとリージョンを指定します。
    	cfg := oss.LoadDefaultConfig().
    		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
    		WithRegion(region)
    
    	// OSS クライアントを作成します。
    	client := oss.NewClient(cfg)
    
    	// GetObject リクエストの署名付き URL を生成します。
    	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
    		Bucket: oss.Ptr(bucketName),
    		Key:    oss.Ptr(objectName),
    	},
    		oss.PresignExpires(10*time.Minute),
    	)
    	if err != nil {
    		log.Fatalf("オブジェクトの署名付き URL の取得に失敗しました %v", err)
    	}
    
    	log.Printf("リクエストメソッド: %v\n", result.Method)
    	log.Printf("リクエストの有効期限: %v\n", result.Expiration)
    	log.Printf("リクエスト URL: %v\n", result.URL)
    	if len(result.SignedHeaders) > 0 {
    		// HTTP GET リクエストを許可する署名付き URL を生成するときにリクエストヘッダーを指定する場合は、署名付き URL を使用して開始された GET リクエストにリクエストヘッダーが含まれていることを確認してください。 これにより、リクエストの失敗と署名エラーを防ぎます。
    		log.Printf("署名済みヘッダー:\n")
    		for k, v := range result.SignedHeaders {
    			log.Printf("%v: %v\n", k, v)
    		}
    	}
    }
    
  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); // この手順により、署名付き URL がドキュメントに存在することが保証されます。
            link.click(); // 署名付き URL をクリックして、オブジェクトのダウンロードをシミュレートします。
            link.remove(); // オブジェクトのダウンロード後、署名付き URL を削除します。
            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 を生成する方法の例を示しています。

package main

import (
	"context"
	"flag"
	"log"
	"time"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// グローバル変数を指定します。
var (
	region     string // バケットが配置されているリージョン。
	bucketName string // バケットの名前。
	objectName string // オブジェクトの名前。
)

// コマンドラインパラメーターを初期化するために使用される init 関数を指定します。
func init() {
	flag.StringVar(&region, "region", "", "バケットが配置されているリージョン。")
	flag.StringVar(&bucketName, "bucket", "", "バケットの名前。")
	flag.StringVar(&objectName, "object", "", "オブジェクトの名前。")
}

func main() {
	// コマンドラインパラメーターを解析します。
	flag.Parse()

	// バケット名が空かどうかを確認します。
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("無効なパラメーター、バケット名が必要です")
	}

	// リージョンが空かどうかを確認します。
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("無効なパラメーター、リージョンが必要です")
	}

	// オブジェクト名が空かどうかを確認します。
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("無効なパラメーター、オブジェクト名が必要です")
	}

	// デフォルトの構成を読み込み、認証情報プロバイダーとリージョンを指定します。
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// OSS クライアントを作成します。
	client := oss.NewClient(cfg)

	// GetObject リクエストの署名付き URL を生成します。
	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
		Bucket:    oss.Ptr(bucketName),
		Key:       oss.Ptr(objectName),
		VersionId: oss.Ptr("yourVersionId"), // バージョン ID を指定します。
	},
		oss.PresignExpires(10*time.Minute),
	)
	if err != nil {
		log.Fatalf("オブジェクトの署名付き URL の取得に失敗しました %v", err)
	}
	log.Printf("オブジェクトの署名付き URL の取得結果: %#v\n", result)
	log.Printf("オブジェクト URL の取得: %#v\n", result.URL)
}

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

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

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

    package main
    
    import (
    	"context"
    	"flag"
    	"log"
    
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
    )
    
    // グローバル変数を指定します。
    var (
    	region     string // バケットが配置されているリージョン。
    	bucketName string // バケットの名前。
    	objectName string // オブジェクトの名前。
    )
    
    // コマンドラインパラメーターを初期化するために使用される init 関数を指定します。
    func init() {
    	flag.StringVar(&region, "region", "", "バケットが配置されているリージョン。")
    	flag.StringVar(&bucketName, "bucket", "", "バケットの名前。")
    	flag.StringVar(&objectName, "object", "", "オブジェクトの名前。")
    }
    
    func main() {
    	// コマンドラインパラメーターを解析します。
    	flag.Parse()
    
    	// バケット名が指定されているかどうかを確認します。
    	if len(bucketName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("無効なパラメーター、バケット名が必要です")
    	}
    
    	// リージョンが指定されているかどうかを確認します。
    	if len(region) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("無効なパラメーター、リージョンが必要です")
    	}
    
    	// オブジェクトが指定されているかどうかを確認します。
    	if len(objectName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("無効なパラメーター、オブジェクト名が必要です")
    	}
    
    	// デフォルトの構成を読み込み、認証情報プロバイダーとリージョンを指定します。
    	cfg := oss.LoadDefaultConfig().
    		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
    		WithRegion(region)
    
    	// OSS クライアントを作成します。
    	client := oss.NewClient(cfg)
    
    	// GetObject リクエストの署名付き URL を生成します。
    	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
    		Bucket: oss.Ptr(bucketName),
    		Key:    oss.Ptr(objectName),
    		RequestCommon: oss.RequestCommon{
    			Headers: map[string]string{
    				"Content-Type": "text/txt; charset=utf-8", // リクエストヘッダーを設定します。 Content-Type ヘッダーの値を 'text/txt; charset=utf-8' に設定します。
    			},
    		},
    	},
    	)
    	if err != nil {
    		log.Fatalf("オブジェクトの署名付き URL の取得に失敗しました %v", err)
    	}
    
    	log.Printf("リクエストメソッド: %v\n", result.Method)
    	log.Printf("リクエストの有効期限: %v\n", result.Expiration)
    	log.Printf("リクエスト URL: %v\n", result.URL)
    	if len(result.SignedHeaders) > 0 {
    		// HTTP GET リクエストを許可する署名付き URL を生成するときにリクエストヘッダーを指定する場合は、署名付き URL を使用して開始された GET リクエストにリクエストヘッダーが含まれていることを確認してください。
    		log.Printf("署名済みヘッダー:\n")
    		for k, v := range result.SignedHeaders {
    			log.Printf("%v: %v\n", k, v)
    		}
    	}
    }
    
  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=LTAI5tKHJzUF3wMmACXgf1aH****************&x-oss-signature=f1746f121783eed5dab2d665da95fbca08505263e27476a46f88dbe3702af8a9***************************************" \
    -H "Content-Type: text/plain; charset=utf-8" \
    -o "myfile.txt"
    package main
    
    import (
    	"io"
    	"log"
    	"net/http"
    	"os"
    )
    
    func main() {
    	// 生成された署名付き URL を指定します。
    	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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"
    
    	// HTTP GET リクエストを許可する署名付き URL を使用してファイルをダウンロードします。
    	req, err := http.NewRequest(http.MethodGet, url, nil)
    	if err != nil {
    		log.Fatalf("PUT リクエストの作成に失敗しました: %v", err)
    	}
    
    	// Content-Type リクエストヘッダーを指定します。
    	req.Header.Set("Content-Type", "text/txt; charset=utf-8")
    
    	// リクエストを開始します。
    	client := &http.Client{}
    	resp, err := client.Do(req)
    	if err != nil {
    		log.Fatalf("ファイルのアップロードに失敗しました: %v", err)
    	}
    	defer resp.Body.Close()
    
    	// 書き込まれるファイルのローカルパスを指定します。
    	filePath := "C:/downloads/myfile.txt"
    
    	// ローカルファイルを作成または開きます。
    	file, err := os.Create(filePath)
    	if err != nil {
    		log.Fatalf("ファイルの作成または開くに失敗しました: %v", err)
    	}
    	defer file.Close() // 関数が完了したら、ファイルが閉じられるようにします。
    
    	// io.Copy を使用して、コンテンツをローカルファイルに書き込みます。
    	n, err := io.Copy(file, resp.Body)
    	if err != nil {
    		log.Fatalf("オブジェクトの読み取りに失敗しました %v", err)
    	}
    
    	// レスポンスボディを閉じます。
    	err = resp.Body.Close()
    	if err != nil {
    		log.Printf("レスポンスボディを閉じるのに失敗しました: %v", err)
    	}
    
    	log.Printf("%d バイトをファイルに書き込みました: %s\n", n, filePath)
    }
    

署名付き URL を使用してオブジェクトのダウンロードを強制する

  1. response-content-disposition パラメーターを使用して署名付き URL を生成します。

    package main
    
    import (
    	"context"
    	"flag"
    	"log"
    
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
    )
    
    // グローバル変数を指定します。
    var (
    	region     string // バケットが配置されているリージョン。
    	bucketName string // バケットの名前。
    	objectName string // オブジェクトの名前。
    )
    
    // コマンドラインパラメーターを初期化するために使用される init 関数を指定します。
    func init() {
    	flag.StringVar(&region, "region", "", "バケットが配置されているリージョン。")
    	flag.StringVar(&bucketName, "bucket", "", "バケットの名前。")
    	flag.StringVar(&objectName, "object", "", "オブジェクトの名前。")
    }
    
    func main() {
    	// コマンドラインパラメーターを解析します。
    	flag.Parse()
    
    	// バケット名が空かどうかを確認します。
    	if len(bucketName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("無効なパラメーター、バケット名が必要です")
    	}
    
    	// リージョンが空かどうかを確認します。
    	if len(region) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("無効なパラメーター、リージョンが必要です")
    	}
    
    	// オブジェクト名が空かどうかを確認します。
    	if len(objectName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("無効なパラメーター、オブジェクト名が必要です")
    	}
    
    	// デフォルトの構成を読み込み、認証情報プロバイダーとリージョンを指定します。
    	cfg := oss.LoadDefaultConfig().
    		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
    		WithRegion(region)
    
    	// OSS クライアントを作成します。
    	client := oss.NewClient(cfg)
    
    	// GetObject リクエストの署名付き URL を生成します。
    	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
    		Bucket:                     oss.Ptr(bucketName),
    		Key:                        oss.Ptr(objectName),
    		ResponseContentDisposition: oss.Ptr("attachment;filename=test.txt"),
    	},
    	)
    	if err != nil {
    		log.Fatalf("オブジェクトの署名付き URL の取得に失敗しました %v", err)
    	}
    
    	log.Printf("リクエストメソッド: %v\n", result.Method)
    	log.Printf("リクエストの有効期限: %v\n", result.Expiration)
    	log.Printf("リクエスト URL: %v\n", result.URL)
    	if len(result.SignedHeaders) > 0 {
    		// HTTP GET リクエストを許可する署名付き URL を生成するときにリクエストヘッダーを指定する場合は、署名付き URL を使用して開始された GET リクエストにリクエストヘッダーが含まれていることを確認してください。
    		log.Printf("署名済みヘッダー:\n")
    		for k, v := range result.SignedHeaders {
    			log.Printf("%v: %v\n", k, v)
    		}
    	}
    }
    

  2. クエリパラメーターを含む署名付き URL を使用して、特定のファイルを直接ダウンロードします。

    curl -X GET "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?response-content-disposition=attachment%3B%20filename%3Dtest.txt&x-oss-date=20241113T093321Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************&x-oss-signature=ed5a******************************************************" \
    -o "myfile.txt"
    package main
    
    import (
    	"io"
    	"log"
    	"net/http"
    	"os"
    )
    
    func main() {
    	// 署名付き URL を指定します。
    	url := "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?response-content-disposition=attachment%3B%20filename%3Dtest.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******************************************************"
    
    	// 上記で生成された署名付き URL を使用して、HTTP GET メソッドでオブジェクトをダウンロードします。
    	req, err := http.NewRequest(http.MethodGet, url, nil)
    	if err != nil {
    		log.Fatalf("PUT リクエストの作成に失敗しました: %v", err)
    	}
    
    	// リクエストを開始します。
    	client := &http.Client{}
    	resp, err := client.Do(req)
    	if err != nil {
    		log.Fatalf("ファイルのアップロードに失敗しました: %v", err)
    	}
    	defer resp.Body.Close()
    
    	// 書き込まれるローカルパスを指定します。
    	filePath := "C:/downloads/myfile.txt"
    
    	// ローカルファイルを作成または開きます。
    	file, err := os.Create(filePath)
    	if err != nil {
    		log.Fatalf("ファイルの作成または開くに失敗しました: %v", err)
    	}
    	defer file.Close() // 関数が完了したら、ファイルストリームが閉じられるようにします。
    
    	// ファイルのコンテンツをローカルファイルに書き込みます。
    	n, err := io.Copy(file, resp.Body)
    	if err != nil {
    		log.Fatalf("オブジェクトの読み取りに失敗しました %v", err)
    	}
    
    	// レスポンスボディを閉じます。
    	err = resp.Body.Close()
    	if err != nil {
    		log.Printf("レスポンスボディを閉じるのに失敗しました: %v", err)
    	}
    
    	log.Printf("%d バイトをファイルに書き込みました: %s\n", n, filePath)
    }
    

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

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

package main

import (
	"context"
	"flag"
	"log"
	"time"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// グローバル変数を指定します。
var (
	region     string // バケットが配置されているリージョン。
	bucketName string // バケットの名前。
	objectName string // オブジェクトの名前。
)

// コマンドラインパラメーターを初期化するために使用される init 関数を指定します。
func init() {
	flag.StringVar(&region, "region", "", "バケットが配置されているリージョン。")
	flag.StringVar(&bucketName, "bucket", "", "バケットの名前。")
	flag.StringVar(&objectName, "object", "", "オブジェクトの名前。")
}

func main() {
	// コマンドラインパラメーターを解析します。
	flag.Parse()

	// バケット名が指定されているかどうかを確認します。
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("無効なパラメーター、バケット名が必要です")
	}

	// リージョンが指定されているかどうかを確認します。
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("無効なパラメーター、リージョンが必要です")
	}

	// オブジェクトが指定されているかどうかを確認します。
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("無効なパラメーター、オブジェクト名が必要です")
	}

	// デフォルトの構成を読み込み、認証情報プロバイダー、リージョン、エンドポイント、CNAME の使用を指定します。
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region).
		WithEndpoint("http://static.example.com").
		WithUseCName(true)

	// OSS クライアントを作成します。
	client := oss.NewClient(cfg)

	// GetObject リクエストの署名付き URL を生成します。
	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
		Bucket: oss.Ptr(bucketName),
		Key:    oss.Ptr(objectName),
		//RequestPayer: oss.Ptr("requester"), // リクエスターの ID を指定します。
	},
		oss.PresignExpires(10*time.Minute),
	)
	if err != nil {
		log.Fatalf("オブジェクトの署名付き URL の取得に失敗しました %v", err)
	}

	log.Printf("リクエストメソッド: %v\n", result.Method)
	log.Printf("リクエストの有効期限: %v\n", result.Expiration)
	log.Printf("リクエスト URL: %v\n", result.URL)
	if len(result.SignedHeaders) > 0 {
		// HTTP GET リクエストを許可する署名付き URL を生成するときにリクエストヘッダーを指定する場合は、署名付き URL を使用して開始された GET リクエストにリクエストヘッダーが含まれていることを確認してください。 これにより、リクエストの失敗と署名エラーを防ぎます。
		log.Printf("署名済みヘッダー:\n")
		for k, v := range result.SignedHeaders {
			log.Printf("%v: %v\n", k, v)
		}
	}
}

関連情報

  • 署名付き URL を使用してオブジェクトをダウンロードするために使用される完全なサンプルコードについては、GitHub をご覧ください。

  • 署名付き URL を使用してオブジェクトをダウンロードするために呼び出すことができる API 操作の詳細については、「Presign」をご参照ください。