日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

Go使用預簽名URL下載

默認情況下,OSS Bucket中的文件是私有的,僅文件擁有者可訪問。本文介紹如何使用OSS Go SDK生成帶有過期時間的GET方法簽名URL,以允許他人臨時下載文件。在有效期內可多次訪問,超期后需重新生成。

注意事項

  • 本文示例代碼以華東1(杭州)的地域IDcn-hangzhou為例,默認使用外網Endpoint,如果您希望通過與OSS同地域的其他阿里云產品訪問OSS,請使用內網Endpoint。關于OSS支持的RegionEndpoint的對應關系,請參見OSS地域和訪問域名

  • 本文以從環境變量讀取訪問憑證為例。如何配置訪問憑證,請參見配置訪問憑證

  • 生成GET方法的簽名URL時,您必須具有oss:GetObject權限。具體操作,請參見RAM用戶授權自定義的權限策略

    說明

    在生成簽名 URL 的過程中,SDK 利用本地存儲的密鑰信息,根據特定算法計算出簽名(signature),然后將其附加到 URL 上,以確保 URL 的有效性和安全性。這一系列計算和構造 URL 的操作都是在客戶端完成的,不涉及網絡請求到服務端。因此,生成簽名 URL 時不需要授予調用者特定權限。然而,為避免第三方用戶無法對簽名URL授權的資源執行相關操作,需要確保調用生成簽名 URL 接口的身份主體已被授予相應的權限。

  • 本文示例代碼使用V4簽名URL,有效期最大為7天。更多信息,請參見簽名版本4(推薦)

使用過程

使用簽名URL下載文件的過程如下:

image

方法定義

您可以使用預簽名接口生成預簽名URL,授予對存儲空間中對象的限時訪問權限。在過期時間之前,您可以多次使用預簽名URL。

預簽名接口定義如下:

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

請求參數列表

參數名

類型

說明

ctx

context.Context

請求的上下文

request

*GetObjectRequest

設置需要生成簽名URL的接口名

optFns

...func(*PresignOptions)

(可選)設置過期時間,如果不指定,默認有效期為15分鐘

其中,PresignOptions選項列舉如下:

選項值

類型

說明

Expires

time.Duration

從當前時間開始,多長時間過期。例如設置一個有效期為30分鐘,30 * time.Minute

Expiration

time.Time

絕對過期時間

重要

在簽名版本V4下,有效期最長為7天。同時設置ExpirationExpires時,優先取Expiration。

返回值列表

返回值名

類型

說明

result

*PresignResult

返回結果,包含預簽名URL,HTTP方法,過期時間和參與簽名的請求頭

err

error

請求的狀態,當請求失敗時,err不為nil

其中,PresignResult返回值列舉如下:

參數名

類型

說明

Method

string

HTTP方法,和接口對應,例如GetObject接口,返回GET

URL

string

預簽名URL

Expiration

time.Time

簽名URL的過期時間

SignedHeaders

map[string]string

被簽名的請求頭,例如PutObject接口,設置了Content-Type時,會返回 Content-Type的信息

示例代碼

  1. 文件擁有者生成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", "", "The region in which the bucket is located.")
    	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
    	flag.StringVar(&objectName, "object", "", "The name of the object.")
    }
    
    func main() {
    	// 解析命令行參數
    	flag.Parse()
    
    	// 檢查bucket名稱是否為空
    	if len(bucketName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("invalid parameters, bucket name required")
    	}
    
    	// 檢查region是否為空
    	if len(region) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("invalid parameters, region required")
    	}
    
    	// 檢查object名稱是否為空
    	if len(objectName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("invalid parameters, object name required")
    	}
    
    	// 加載默認配置并設置憑證提供者和區域
    	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),
    		//RequestPayer: oss.Ptr("requester"), // 指定請求者身份
    	},
    		oss.PresignExpires(10*time.Minute),
    	)
    	if err != nil {
    		log.Fatalf("failed to get object presign %v", err)
    	}
    
    	log.Printf("request method:%v\n", result.Method)
    	log.Printf("request expiration:%v\n", result.Expiration)
    	log.Printf("request url:%v\n", result.URL)
    	if len(result.SignedHeaders) > 0 {
    		//當返回結果包含簽名頭時,使用簽名URL發送GET請求時也包含相應的請求頭,以免出現不一致,導致請求失敗和簽名錯誤
    		log.Printf("signed headers:\n")
    		for k, v := range result.SignedHeaders {
    			log.Printf("%v: %v\n", k, v)
    		}
    	}
    }
    
  2. 其他人使用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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"

    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) {
            // 替換為生成的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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********";
            // 填寫文件保存的目標路徑,包括文件名和擴展名。
            String savePath = "C:/downloads/myfile.txt";
    
            try {
                downloadFile(fileURL, savePath);
                System.out.println("Download completed!");
            } catch (IOException e) {
                System.err.println("Error during download: " + 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("No file to download. Server replied HTTP code: " + 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********";
    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("Download completed!");
            });
        } else {
            console.error(`Download failed. Server responded with code: ${response.statusCode}`);
        }
    }).on('error', (err) => {
        console.error("Error during download:", 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"
    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("Download completed!")
        else:
            print(f"No file to download. Server replied HTTP code: {response.status_code}")
    except Exception as e:
        print("Error during download:", 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"
        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("Download completed!")
        } else {
            println("No file to download. Server replied HTTP code:", 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********";
    const savePath = "C:/downloads/myfile.txt"; // 文件將在下載時使用的文件名
    
    fetch(fileURL)
        .then(response => {
            if (!response.ok) {
                throw new Error(`Server replied HTTP code: ${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("Download completed!");
        })
        .catch(error => {
            console.error("Error during download:", 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 "Download completed!";
                } else {
                    return "No file to download. Server replied HTTP code: " + responseCode;
                }
            } catch (Exception e) {
                return "Error during download: " + 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=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********";
            NSString *savePath = @"/Users/your_username/Desktop/myfile.txt"; // 請替換為您的用戶名
            
            // 創建 URL 對象
            NSURL *url = [NSURL URLWithString:fileURL];
            
            // 創建下載任務
            NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                // 錯誤處理
                if (error) {
                    NSLog(@"Error during download: %@", error.localizedDescription);
                    return;
                }
                
                // 檢查數據
                if (!data) {
                    NSLog(@"No data received.");
                    return;
                }
                
                // 保存文件
                NSError *writeError = nil;
                BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath] options:NSDataWritingAtomic error:&writeError];
                if (success) {
                    NSLog(@"Download completed!");
                } else {
                    NSLog(@"Error saving file: %@", writeError.localizedDescription);
                }
            }];
            
            // 啟動任務
            [task resume];
            
            // 讓主線程繼續運行以便異步請求能夠完成
            [[NSRunLoop currentRunLoop] run];
        }
        return 0;
    }

常見使用場景

生成指定版本的文件的GET方法的簽名URL

以下代碼示例在生成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", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// 解析命令行參數
	flag.Parse()

	// 檢查bucket名稱是否為空
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// 檢查region是否為空
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// 檢查object名稱是否為空
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// 加載默認配置并設置憑證提供者和區域
	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("failed to get object presign %v", err)
	}
	log.Printf("get object presign result: %#v\n", result)
	log.Printf("get object url: %#v\n", result.URL)
}

相關文檔

  • 關于預簽名URL的完整示例代碼,請參見GitHub示例

  • 關于預簽名URLAPI接口,請參見Presign