全部产品
Search
文档中心

Object Storage Service:Unduh objek menggunakan URL yang ditandatangani

更新时间:Aug 16, 2025

Secara default, daftar kontrol akses (ACL) dari sebuah objek dalam bucket Object Storage Service (OSS) bersifat pribadi. Hanya pemilik objek yang memiliki izin untuk mengaksesnya. Anda dapat menggunakan OSS SDK untuk Python untuk menghasilkan URL yang ditandatangani yang mengizinkan permintaan HTTP GET dan memiliki periode validitas. Bagikan URL tersebut kepada pengguna untuk sementara waktu agar mereka dapat mengunduh objek. Selama periode validitas, pengguna dapat mengunduh objek berulang kali. Setelah periode validitas berakhir, pengguna harus mendapatkan URL yang ditandatangani baru.

Catatan

  • Dalam topik ini, Titik akhir publik wilayah Tiongkok (Hangzhou) digunakan. Untuk mengakses OSS dari layanan Alibaba Cloud lainnya di wilayah yang sama, gunakan Titik akhir internal. Untuk detail tentang wilayah dan titik akhir yang didukung, lihat Wilayah dan Titik Akhir OSS.

  • Dalam topik ini, kredensial akses diperoleh dari variabel lingkungan. Untuk informasi lebih lanjut tentang cara mengonfigurasi kredensial akses, lihat Konfigurasi Kredensial Akses.

  • Dalam topik ini, instans OSSClient dibuat menggunakan titik akhir OSS. Jika Anda ingin membuat instans OSSClient dengan menggunakan nama domain kustom atau Layanan Token Keamanan (STS), lihat Inisialisasi.

  • Anda tidak memerlukan izin untuk menghasilkan URL yang ditandatangani. Namun, pihak ketiga hanya dapat menggunakan URL yang ditandatangani untuk mengunduh objek jika Anda memiliki izin oss:GetObject. Untuk informasi lebih lanjut, lihat Berikan Kebijakan Akses Kustom kepada Pengguna RAM.

  • Dalam topik ini, URL yang ditandatangani V4 dengan periode validitas tujuh hari digunakan. Untuk informasi lebih lanjut, lihat (Direkomendasikan) Tanda Tangan V4 dalam URL yang Ditandatangani.

Proses

Gambar berikut menunjukkan cara menggunakan URL yang ditandatangani untuk mengunduh objek.

Kode contoh

  1. Kode berikut memberikan contoh cara menghasilkan URL yang ditandatangani yang mengizinkan permintaan HTTP GET:

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    
    # Dapatkan kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
    auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
    
    # Tentukan titik akhir untuk wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah Tiongkok (Hangzhou), atur titik akhir ke https://oss-cn-hangzhou.aliyuncs.com.
    endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
    
    # Tentukan ID wilayah yang sesuai dengan titik akhir. Contoh: cn-hangzhou. Parameter ini diperlukan jika Anda menggunakan algoritma tanda tangan V4.
    region = "cn-hangzhou"
    
    # Tentukan nama bucket Anda.
    bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
    
    # Tentukan jalur lengkap objek. Jangan sertakan nama bucket dalam jalur lengkap. Contoh: exampledir/exampleobject.txt.
    object_name = 'exampledir/exampleobject.txt'
    
    # Hasilkan URL yang ditandatangani yang digunakan untuk mengunduh objek. Dalam contoh ini, periode validitas URL adalah 600 detik.
    # Secara default, OSS mengidentifikasi garis miring (/) dalam jalur lengkap objek sebagai karakter escape dalam proses penandatanganan. Oleh karena itu, URL yang ditandatangani tidak dapat langsung digunakan.
    # Atur parameter slash_safe menjadi True. Dengan cara ini, OSS tidak mengidentifikasi garis miring (/) dalam jalur lengkap objek sebagai karakter escape, dan URL yang ditandatangani dapat langsung digunakan.
    url = bucket.sign_url('GET', object_name, 600, slash_safe=True)
    print('URL yang ditandatangani:', url)
  2. Kode berikut memberikan contoh cara menggunakan URL yang ditandatangani yang mengizinkan permintaan HTTP GET untuk mengunduh objek:

    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) {
            // Ganti URL dengan URL yang ditandatangani yang dihasilkan untuk permintaan GET.
            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******************************************************";
            // Tentukan jalur tujuan untuk menyimpan file, termasuk nama file dan ekstensi.
            String savePath = "C:/downloads/myfile.txt";
    
            try {
                downloadFile(fileURL, savePath);
                System.out.println("Unduhan selesai!");
            } catch (IOException e) {
                System.err.println("Kesalahan selama unduhan: " + 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");
    
            // Periksa kode respons.
            int responseCode = httpConn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                // Aliran masukan.
                InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
                // Aliran keluaran.
                FileOutputStream outputStream = new FileOutputStream(savePath);
    
                byte[] buffer = new byte[4096]; // Buffer.
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
    
                outputStream.close();
                inputStream.close();
            } else {
                System.out.println("Tidak ada file untuk diunduh. Server membalas dengan kode 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("Unduhan selesai!");
            });
        } else {
            console.error(`Unduhan gagal. Server merespons dengan kode: ${response.statusCode}`);
        }
    }).on('error', (err) => {
        console.error("Kesalahan selama unduhan:", 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("Unduhan selesai!")
        else:
            print(f"Tidak ada file untuk diunduh. Server membalas dengan kode HTTP: {response.status_code}")
    except Exception as e:
        print("Kesalahan selama unduhan:", 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("Unduhan selesai!")
        } else {
            println("Tidak ada file untuk diunduh. Server membalas dengan kode 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"; // Nama file yang akan digunakan untuk unduhan.
    
    fetch(fileURL)
        .then(response => {
            if (!response.ok) {
                throw new Error(`Server membalas dengan kode HTTP: ${response.status}`);
            }
            return response.blob(); // Ubah respons menjadi blob.
        })
        .then(blob => {
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = savePath; // Tetapkan nama file yang diunduh.
            document.body.appendChild(link); // Langkah ini memastikan bahwa tautan ada di dokumen.
            link.click(); // Simulasikan klik pada tautan unduhan.
            link.remove(); // Hapus tautan setelah unduhan selesai.
            console.log("Unduhan selesai!");
        })
        .catch(error => {
            console.error("Kesalahan selama unduhan:", 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"; // Jalur penyimpanan yang dimodifikasi.
            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 "Unduhan selesai!";
                } else {
                    return "Tidak ada file untuk diunduh. Server membalas dengan kode HTTP: " + responseCode;
                }
            } catch (Exception e) {
                return "Kesalahan selama unduhan: " + e.getMessage();
            }
        }
    }

    Objective-C

    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // Tentukan URL file dan jalur penyimpanan (ubah ke jalur yang valid).
            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"; // Ganti ini dengan nama pengguna Anda.
            
            // Buat objek URL.
            NSURL *url = [NSURL URLWithString:fileURL];
            
            // Buat tugas unduhan.
            NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                // Tangani kesalahan.
                if (error) {
                    NSLog(@"Kesalahan selama unduhan: %@", error.localizedDescription);
                    return;
                }
                
                // Periksa data.
                if (!data) {
                    NSLog(@"Tidak ada data yang diterima.");
                    return;
                }
                
                // Simpan file.
                NSError *writeError = nil;
                BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath] options:NSDataWritingAtomic error:&writeError];
                if (success) {
                    NSLog(@"Unduhan selesai!");
                } else {
                    NSLog(@"Kesalahan menyimpan file: %@", writeError.localizedDescription);
                }
            }];
            
            // Mulai tugas.
            [task resume];
            
            // Pertahankan thread utama agar permintaan asinkron dapat diselesaikan.
            [[NSRunLoop currentRunLoop] run];
        }
        return 0;
    }

Skenario lainnya

Hasilkan URL yang ditandatangani yang mengizinkan permintaan HTTP GET untuk versi tertentu dari objek

Kode contoh berikut memberikan contoh cara menghasilkan URL yang ditandatangani yang mengizinkan permintaan HTTP GET untuk versi tertentu dari objek:

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

# Dapatkan kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# Tentukan titik akhir untuk wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah Tiongkok (Hangzhou), atur titik akhir ke https://oss-cn-hangzhou.aliyuncs.com.
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"

# Tentukan ID wilayah yang sesuai dengan titik akhir. Contoh: cn-hangzhou. Parameter ini diperlukan jika Anda menggunakan algoritma tanda tangan V4.
region = "cn-hangzhou"

# Tentukan nama bucket Anda.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)

# Tentukan jalur lengkap objek. Jangan sertakan nama bucket dalam jalur lengkap. Contoh: exampledir/exampleobject.txt.
object_name = 'exampledir/exampleobject.txt'

# Tentukan header permintaan.
headers = dict()
# Tentukan ID versi objek.
headers["versionId"] = "CAEQARiBgID8rumR2hYiIGUyOTAyZGY2MzU5MjQ5ZjlhYzQzZjNlYTAyZDE3****"

# Hasilkan URL yang ditandatangani dan atur periode validitas URL yang ditandatangani menjadi 600 detik.
# Secara default, OSS mengidentifikasi garis miring (/) dalam jalur lengkap objek sebagai karakter escape dalam proses penandatanganan. Oleh karena itu, URL yang ditandatangani tidak dapat langsung digunakan.
# Atur parameter slash_safe menjadi True. Dengan cara ini, OSS tidak mengidentifikasi garis miring (/) dalam jalur lengkap objek sebagai karakter escape, dan URL yang ditandatangani dapat langsung digunakan.
url = bucket.sign_url('PUT', object_name, 600, slash_safe=True, headers=headers)
print('URL yang ditandatangani:', url)

Gunakan URL yang ditandatangani yang berisi header permintaan tertentu untuk mengunduh objek

Jika Anda menentukan header permintaan saat menghasilkan URL yang ditandatangani yang mengizinkan permintaan HTTP GET, pastikan header permintaan tersebut disertakan dalam permintaan GET yang diinisiasi menggunakan URL yang ditandatangani. Ini mencegah kegagalan permintaan dan kesalahan tanda tangan.

  1. Hasilkan URL yang ditandatangani yang berisi header permintaan tertentu dan mengizinkan permintaan HTTP GET.

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    
    # Dapatkan kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
    auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
    
    # Tentukan titik akhir untuk wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah Tiongkok (Hangzhou), atur titik akhir ke https://oss-cn-hangzhou.aliyuncs.com.
    endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
    
    # Tentukan ID wilayah yang sesuai dengan titik akhir. Contoh: cn-hangzhou. Parameter ini diperlukan jika Anda menggunakan algoritma tanda tangan V4.
    region = "cn-hangzhou"
    
    # Tentukan nama bucket Anda.
    bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
    
    # Tentukan jalur lengkap objek. Jangan sertakan nama bucket dalam jalur lengkap. Contoh: exampledir/exampleobject.txt.
    object_name = 'exampledir/exampleobject.txt'
    
    # Tentukan header permintaan.
    headers = dict()
    # Tentukan header Content-Type.
    headers['Content-Type'] = 'text/plain; charset=utf8'
    
    # Tentukan parameter kueri HTTP.
    params = dict()
    # Konfigurasikan pembatasan bandwidth koneksi tunggal. Unit: bit/s. Dalam contoh ini, ambang batas pembatasan diatur menjadi 100 KB/s.
    # params['x-oss-traffic-limit'] = str(100 * 1024 * 8)
    # Tentukan alamat IP atau Blok CIDR.
    # params['x-oss-ac-source-ip'] = "127.0.0.1"
    # Tentukan jumlah digit 1 dalam subnet mask.
    # params['x-oss-ac-subnet-mask'] = "32"
    # Tentukan ID VPC.
    # params['x-oss-ac-vpc-id'] = "vpc-t4nlw426y44rd3iq4xxxx"
    # Tentukan apakah permintaan forward diizinkan.
    # params['x-oss-ac-forward-allow'] = "true"
    
    # Hasilkan URL yang ditandatangani yang digunakan untuk mengunduh objek. Dalam contoh ini, periode validitas URL adalah 600 detik.
    # Secara default, OSS mengidentifikasi garis miring (/) dalam jalur lengkap objek sebagai karakter escape dalam proses penandatanganan. Oleh karena itu, URL yang ditandatangani tidak dapat langsung digunakan.
    # Atur parameter slash_safe menjadi True. Dengan cara ini, OSS tidak mengidentifikasi garis miring (/) dalam jalur lengkap objek sebagai karakter escape, dan URL yang ditandatangani dapat langsung digunakan.
    url = bucket.sign_url('GET', object_name, 600, slash_safe=True, headers=headers, params=params)
    print('URL yang ditandatangani:', url)
  2. Gunakan URL yang ditandatangani dan tentukan header permintaan dalam permintaan untuk mengunduh objek.

    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****************&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):
        """
        Gunakan URL yang ditandatangani untuk mengunduh objek.
    
        :param signed_url: URL yang ditandatangani
        :param file_path: jalur lengkap objek untuk diunduh
        :param headers: header permintaan. Parameter ini opsional.
        :param metadata: metadata pengguna. Parameter ini opsional.
        :return: None
        """
        if not headers:
            headers = {}
    
        try:
            response = requests.get(signed_url, headers=headers, stream=True)
            print(f"Status kode unduhan: {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:  # filter out keep-alive new chunks
                            file.write(chunk)
                print("Objek telah diunduh")
            else:
                print("Unduhan gagal")
                print(response.text)
        except Exception as e:
            print(f"Terjadi kesalahan: {e}")
    
    if __name__ == "__main__":
        # Ganti <signedUrl> dengan URL yang ditandatangani yang dihasilkan.
        signed_url = "<signedUrl>"
        file_path = "/Users/yourLocalPath>/Downloads/downloadedFile.txt" // Tentukan jalur lokal di mana objek disimpan.
    
        headers = {
            "Content-Type": "text/plain; charset=utf-8",
            # Header lain yang diperlukan
        }
    
        download_file(signed_url, file_path, headers=headers)

Hasilkan URL yang ditandatangani dengan menggunakan nama domain kustom

Kode berikut memberikan contoh cara menghasilkan URL yang ditandatangani menggunakan nama domain kustom.

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

# Dapatkan kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# Tentukan ID wilayah yang sesuai dengan titik akhir. Contoh: cn-hangzhou. Parameter ini diperlukan jika Anda menggunakan algoritma tanda tangan V4.
region = "cn-hangzhou"

# Tentukan nama domain kustom. Contoh: static.example.com.
endpoint = 'http://static.example.com'

# Tentukan nama bucket Anda.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region, is_cname=True)


# Tentukan jalur lengkap objek. Jangan sertakan nama bucket dalam jalur lengkap. Contoh: exampledir/exampleobject.txt.
object_name = 'exampledir/exampleobject.txt'

# Hasilkan URL yang ditandatangani yang digunakan untuk mengunduh objek. Dalam contoh ini, periode validitas URL adalah 600 detik.
# Secara default, OSS mengidentifikasi garis miring (/) dalam jalur lengkap objek sebagai karakter escape dalam proses penandatanganan. Oleh karena itu, URL yang ditandatangani tidak dapat langsung digunakan.
# Atur parameter slash_safe menjadi True. Dengan cara ini, OSS tidak mengidentifikasi garis miring (/) dalam jalur lengkap objek sebagai karakter escape, dan URL yang ditandatangani dapat langsung digunakan.
url = bucket.sign_url('GET', object_name, 600, slash_safe=True, params=params)
print('URL yang ditandatangani:', url)