All Products
Search
Document Center

Object Storage Service:Download objects by using presigned URLs

Last Updated:Apr 28, 2025

By default, objects in an Object Storage Service (OSS) bucket are private and can be accessed only by the object owner. However, the object owner can authorize others to temporarily access and download private objects by providing them with presigned URLs.

Notes

  • In this topic, the public endpoint of the China (Hangzhou) region is used. If you want to access OSS from other Alibaba Cloud services in the same region as OSS, use an internal endpoint. For more information about OSS regions and endpoints, see Regions and endpoints.

  • You do not need specific permissions to generate a presigned URL. However, to allow others to use the presigned URL to download an object, you must have the oss:GetObject permission. For more information, see Common examples of RAM policies.

  • A presigned URL can be used multiple times within its validity period. After the presigned URL expires, you must perform Step 1 to generate a new presigned URL to continue accessing the object.

Process overview

The following flowchart shows how to download an object by using a presigned URL.

image

Procedure

Step 1: The object owner generates a presigned URL for the GET method

Note
  • When you generate a presigned URL by using the OSS console or ossbrowser, you can specify a maximum validity period of 32,400 seconds (9 hours).

  • When you generate a presigned URL by using ossutil or OSS SDKs, you can specify a maximum validity period of 7 days.

  • If you generate a presigned URL by using a Security Token Service (STS) token, you can specify a maximum validity period of 43,200 seconds (12 hours).

Use the OSS console

To generate a presigned URL by using the OSS console, perform the following steps:

  1. Log on to the OSS console.

  2. Click Buckets, and then click the name of the bucket that you want to access.

  3. In the left-side navigation pane, choose Object Management > Objects.

  4. Generate a presigned URL.

    1. Click the name of the object that you want to authorize third-party users to download.

    2. In the View Details panel, configure the following parameters and click Copy Object URL.

      image

      Parameter

      Description

      Validity Period

      If the ACL of the object that you want to share is private, you must set a validity period for the URL of the object.

      Valid values: 60 to 32400

      Unit: seconds

      To generate a URL that has a longer validity period, you can use tools such as OSS SDKs and ossutil.

      Custom Domain Name

      To ensure that an image or webpage object is previewed instead of being downloaded when it is accessed by using a URL, use the custom domain name that is mapped to the bucket.

      This parameter is available only when a custom domain name is mapped to the bucket. For more information, see Map custom domain names.

      Use HTTPS

      By default, the generated URL uses the HTTPS protocol. To use the HTTP protocol to generate the URL of an object, turn off Use HTTPS.

Use ossbrowser

ossbrowser supports object-level operations similar to those supported by the console. Follow the instructions on the ossbrowser interface to obtain a signed URL. For more information about how to use ossbrowser, see Common operations.

Use Alibaba Cloud SDKs

The following sample code shows how to generate a presigned URL by using OSS SDKs for common programming languages.

Java

For more information about the SDK, see Download objects by using presigned URLs in Java.

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;

import java.net.URL;
import java.util.Date;

public class Demo {
    public static void main(String[] args) throws Throwable {
        // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the name of the bucket. Example: examplebucket. 
        String bucketName = "examplebucket";
        // Specify the full path of the object. Example: exampleobject.txt. Do not include the bucket name in the full path of the object. 
        String objectName = "exampleobject.txt";
        // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. 
        String region = "cn-hangzhou";

        // Create an OSSClient instance. 
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            // Specify the validity period of the presigned URL. Unit: milliseconds. In this example, the validity period is 1 hour. 
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
            // Generate a presigned URL that allows HTTP GET requests. In this example, no additional request headers are specified. Other users can access the relevant content directly by using the browser. 
            URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
            System.out.println(url);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

Python

For more information about the SDK, see Download objects by using presigned URLs in Python.

import argparse
import alibabacloud_oss_v2 as oss

# Create a command-line parameter parser and describe the purpose of the script.
parser = argparse.ArgumentParser(description="presign get object sample")

# Specify the --region parameter, which specifies the region in which the bucket is located. This command line parameter is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Specify the --bucket parameter to indicate the name of the bucket in which the object is stored. This parameter is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Specify the --endpoint parameter, which specifies the endpoint that other services can use to access OSS. This command line parameter is optional.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Specify the --key parameter, which specifies the name of the object. This command line parameter is required.
parser.add_argument('--key', help='The name of the object.', required=True)

def main():
    # Parse the command line parameters to obtain the values specified by the user.
    args = parser.parse_args()

    # From the environment variables, load the authentication information required to access OSS.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Use the default configurations of the SDK to create a configuration object and specify the credential provider.
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    
    # Specify the region attribute of the configuration object based on the command line parameters provided by the user.
    cfg.region = args.region

    # If a custom endpoint is provided, update the endpoint attribute of the cfg object with the provided endpoint.
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # Use the preceding configuration to initialize the OSSClient instance and allow the instance to interact with OSS.
    client = oss.Client(cfg)

    # Initiate a request to generate a presigned URL.
    pre_result = client.presign(
        oss.GetObjectRequest(
            bucket=args.bucket,  # Specify the bucket name.
            key=args.key,        # Specify the object key.
        )
    )

    # Display the HTTP method, expiration time, and presigned URL.
    print(f'method: {pre_result.method},'
          f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
          f' url: {pre_result.url}'
    )

    # Display the signed headers.
    for key, value in pre_result.signed_headers.items():
        print(f'signed headers key: {key}, signed headers value: {value}')

# Call the main function to start the processing logic when the script is directly run.
if __name__ == "__main__":
    main()  # Script entry point, program flow starts here

Go

For more information about the SDK, see Download objects by using presigned URLs in Go.

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"
)

// Specify the global variables.
var (
	region: string; // The region in which the bucket is located.
	bucketName string // The name of the bucket.
	objectName string // The name of the object.
)

// Specify the init function used to initialize command line parameters.
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() {
	// Parse command line parameters.
	flag.Parse()

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// Load the default configurations and specify the credential provider and region.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Generate a presigned URL for the GetObject request.
	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("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 {
		// If you specify request headers when you generate a presigned URL that allows HTTP GET requests, make sure that the request headers are included in the GET request initiated by using the presigned URL. This prevents request failures and signature errors.
		log.Printf("signed headers:\n")
		for k, v := range result.SignedHeaders {
			log.Printf("%v: %v\n", k, v)
		}
	}
}

Node.js

For more information about the SDK, see Download objects by using presigned URLs in Node.js.

const OSS = require("ali-oss");

// Specify a function used to generate a presigned URL.
async function generateSignatureUrl(fileName) {
  // Obtain the presigned URL.
  const client = await new OSS({
      // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
      accessKeyId: process.env.OSS_ACCESS_KEY_ID,
      accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
      bucket: 'examplebucket',
      // Specify the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set the region to oss-cn-hangzhou.
      region: 'oss-cn-hangzhou',
      // Set secure to true and use HTTPS to prevent the generated download link from being blocked by the browser.
      secure: true,
      authorizationV4: true
  });

  return await client.signatureUrlV4('GET', 3600, {
      headers: {} // Specify the request headers based on the actual request headers.
  }, fileName);
}
// Call the function and pass in the name of the object.
generateSignatureUrl('yourFileName').then(url => {
  console.log('Generated Signature URL:', url);
}).catch(err => {
  console.error('Error generating signature URL:', err);
});

PHP

For more information about the SDK, see Download objects by using presigned URLs in PHP.

<?php

// Include the autoload file to load dependency libraries.
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// Specify descriptions for command line arguments.
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // (Required) Specify the region in which the bucket is located.
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // (Optional) Specify the endpoint that can be used by other services for accessing OSS.
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // (Required) Specify the name of the bucket.
    "key" => ['help' => 'The name of the object', 'required' => True], // (Required) Specify the name of the object.
];

// Convert the descriptions to a list of long options required by getopt.
// Add a colon (:) to the end of each parameter to indicate that a value is required.
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// Parse command line parameters.
$options = getopt("", $longopts);

// Check whether the required parameters are missing.
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // Get the help information for the parameter
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // Exit the program if a required parameter is missing.
    }
}

// Obtain values from the parsed parameters.
$region = $options["region"]; // The region in which the bucket is located.
$bucket = $options["bucket"]; // The name of the bucket.
$key = $options["key"];       // The name of the object.

// Load access credentials from environment variables.
// Use EnvironmentVariableCredentialsProvider to retrieve the AccessKey ID and AccessKey secret from environment variables.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// Use the default configuration of the SDK.
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // Set the credential provider.
$cfg->setRegion($region); // Set the region in which the bucket is located.
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // If an endpoint is provided, set the endpoint.
}

// Create an OSSClient instance.
$client = new Oss\Client($cfg);

// Create a GetObjectRequest object for downloading the object.
$request = new Oss\Models\GetObjectRequest(bucket:$bucket, key:$key);

// Call the presign method to generate a presigned URL.
$result = $client->presign($request);

// Print the presigned result.
// Output the presigned URL, which users can directly use for download operations.
print(
    'get object presign result:' . var_export($result, true) . PHP_EOL . // Detailed information about the presigned result.
    'get object url:' . $result->url . PHP_EOL                           // The presigned URL for directly downloading the object.
);

.NET

For more information about the SDK, see Download objects by using presigned URLs in .NET.

using Aliyun.OSS;
using Aliyun.OSS.Common;
// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// Specify the name of the bucket. Example: examplebucket. 
var bucketName = "examplebucket";
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
var objectName = "exampledir/exampleobject.txt";
var objectContent = "More than just cloud.";
// Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. 
const string region = "cn-hangzhou";

// Create a ClientConfiguration instance and modify the default parameter settings based on your requirements. 
var conf = new ClientConfiguration();

// Specify the V4 signature algorithm. 
conf.SignatureVersion = SignatureVersion.V4;

// Create an OSSClient instance. 
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
conf.SetRegion(region);
try
{
    // Generate a presigned URL. 
    var generatePresignedUriRequest = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Put)
    {
        // Set the validity period of the presigned URL. Default value: 3600. Unit: seconds. 
        Expiration = DateTime.Now.AddHours(1),
    };
    var signedUrl = client.GeneratePresignedUri(generatePresignedUriRequest);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}

Android

For more information about the SDK, see Download objects by using presigned URLs in Android.

// Specify the name of the bucket. Example: examplebucket. 
String bucketName = "examplebucket";
// Specify the full path of the source object. Do not include the bucket name in the full path. Example: exampleobject.txt. 
String objectKey = "exampleobject.txt";
String url = null;
try {
    // Generate a presigned URL to download the object. 
    GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectKey);
    // Set the validity period of the presigned URL to 30 minutes. 
    request.setExpiration(30*60);
    request.setMethod(HttpMethod.GET);
    url = oss.presignConstrainedObjectURL(request);
    Log.d("url", url);
} catch (ClientException e) {
    e.printStackTrace();
}

iOS

For more information about the SDK, see Download objects by using presigned URLs in iOS.

// Specify the name of the bucket. 
NSString *bucketName = @"examplebucket";
// Specify the name of the object. 
NSString *objectKey = @"exampleobject.txt";
__block NSString *urlString;
// Generate a presigned URL with a validity period for downloading the object. In this example, the validity period of the URL is 30 minutes. 
OSSTask *task = [client presignConstrainURLWithBucketName:bucketName
                                            withObjectKey:objectKey
                                               httpMethod:@"GET"
                                   withExpirationInterval:30 * 60
                                           withParameters:@{}];
[task continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
    if (task.error) {
        NSLog(@"presign error: %@", task.error);
    } else {
        urlString = task.result;
        NSLog(@"url: %@", urlString);
    }
    return nil;
}];

C++

For more information about the SDK, see Download objects by using presigned URLs in C++.

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize information about the account that is used to access OSS. */
            
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou.   * /
    std::string Region = "yourRegion";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. */ 
    std::string GetobjectUrlName = "exampledir/exampleobject.txt";

    /* Initialize resources, such as network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    /* Specify the validity period of the pre-signed URL. The maximum validity period is 32,400. Unit: seconds. */
    std::time_t t = std::time(nullptr) + 1200;
    /* Generate a pre-signed URL. */
    auto genOutcome = client.GeneratePresignedUrl(BucketName, GetobjectUrlName, t, Http::Get);
    if (genOutcome.isSuccess()) {
        std::cout << "GeneratePresignedUrl success, Gen url:" << genOutcome.result().c_str() << std::endl;
    }
    else {
        /* Handle exceptions. */
        std::cout << "GeneratePresignedUrl fail" <<
        ",code:" << genOutcome.error().Code() <<
        ",message:" << genOutcome.error().Message() <<
        ",requestId:" << genOutcome.error().RequestId() << std::endl;
        return -1;
    }

    /* Release resources, such as network resources. */
    ShutdownSdk();
    return 0;
}

Ruby

For more information about the SDK, see Download objects by using presigned URLs in Ruby.

require 'aliyun/oss'

client = Aliyun::OSS::Client.new(
  # In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
  endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
  # Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
  access_key_id: ENV['OSS_ACCESS_KEY_ID'],
  access_key_secret: ENV['OSS_ACCESS_KEY_SECRET']
)
# Specify the name of the bucket. Example: examplebucket. 
bucket = client.get_bucket('examplebucket')

# Generate a presigned URL that is used to download the object and set its validity period to 3,600 seconds. 
puts bucket.object_url('my-object', true, 3600)

C

For more information about the SDK, see Download objects by using presigned URLs in C.

#include "oss_api.h"
#include "aos_http_io.h"
/* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
const char *endpoint = "yourEndpoint";
/* Specify the name of the bucket. Example: examplebucket. */
const char *bucket_name = "examplebucket";
/* Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. */
const char *object_name = "exampledir/exampleobject.txt";
/* Specify the full path of the local file. */
const char *local_filename = "yourLocalFilename";

void init_options(oss_request_options_t *options)
{
    options->config = oss_config_create(options->pool);
    /* Use a char* string to initialize aos_string_t. */
    aos_str_set(&options->config->endpoint, endpoint);
    /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
    aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
    aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
    /* Specify whether to use CNAME. The value 0 indicates that CNAME is not used. */
    options->config->is_cname = 0;
    /* Configure network parameters, such as the timeout period. */
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
    /* Call the aos_http_io_initialize method in main() to initialize global resources, such as network and memory resources. */
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* Create a memory pool to manage memory. aos_pool_t is equivalent to apr_pool_t. The code that is used to create a memory pool is included in the APR library. */
    aos_pool_t *pool;
    /* Create a memory pool. The value of the second parameter is NULL. This value specifies that the pool does not inherit other memory pools. */
    aos_pool_create(&pool, NULL);
    /* Create and initialize options. This parameter includes global configuration information, such as endpoint, access_key_id, access_key_secret, is_cname, and curl. */
    oss_request_options_t *oss_client_options;
    /* Allocate memory resources in the memory pool to the options. */
    oss_client_options = oss_request_options_create(pool);
    /* Initialize oss_client_options. */
    init_options(oss_client_options);
    /* Initialize the parameters. */
    aos_string_t bucket;
    aos_string_t object;
    aos_string_t file;    
    aos_http_request_t *req;
    apr_time_t now;
    char *url_str;
    aos_string_t url;
    int64_t expire_time; 
    int one_hour = 3600;
    aos_str_set(&bucket, bucket_name);
    aos_str_set(&object, object_name);
    aos_str_set(&file, local_filename);
    expire_time = now / 1000000 + one_hour;    
    req = aos_http_request_create(pool);
    req->method = HTTP_GET;
    now = apr_time_now();  
    /* Specify the validity period. Unit: microseconds * /
    expire_time = now / 1000000 + one_hour;
    /* Generate a signed URL. */
    url_str = oss_gen_signed_url(oss_client_options, &bucket, &object, expire_time, req);
    aos_str_set(&url, url_str);
    printf("Temporary download URL: %s\n", url_str);     
    /* Release the memory pool. This operation releases memory resources allocated for the request. */
    aos_pool_destroy(pool);
    /* Release the allocated global resources. */
    aos_http_io_deinitialize();
    return 0;
}

The following line provides an example of a presigned URL:

https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-process=image%2Fresize%2Cp_10&x-oss-date=20241115T095058Z&x-oss-expires=3600&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************%2F20241115%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=6e7a*********************************************

Use ossutil

The following sample command generates a presigned URL for the example.txt object located in the specified bucket, enabling 15-minute access to the object:

ossutil presign oss://examplebucket/example.txt

For more information about how to generate a presigned URL by using ossutil, see presign (Generate a presigned URL).

Step 2: Other users download files using the pre-signed URL with the GET method

Use a browser

Copy the presigned URL, paste it into the address bar of a browser, and press Enter.

Use the curl command

In the terminal, enter the following command and replace <presigned_url> with the presigned URL generated in step 1.

curl -SO "<presigned_url>"

Run the following command in a terminal. Replace <presigned_url> with the presigned URL generated in Step 1.

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******************************************************"

Download using the wget command

Enter the following command in the terminal, replace <presigned_url> with the presigned URL generated in step one, and the file will be saved in the current folder with the custom filename example.txt.

wget -O example.txt "<presigned_url>"

Sample command:

wget -O example.txt "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*********************************************"

Use OSS SDKs

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) {
        // Specify the presigned URL that allows HTTP GET requests. 
        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******************************************************";
        // Specify the path in which the downloaded object is stored, including the object name and extension. 
        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");

        // Specify the response code.
        int responseCode = httpConn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            // Configure the input stream.
            InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
            // Configure the output stream.
            FileOutputStream outputStream = new FileOutputStream(savePath);

            byte[] buffer=new byte[4096]; // Specify the size of the buffer.
            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();
    }
}

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("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=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("Download completed!")
    } else {
        println("No file to download. Server replied HTTP code:", response.StatusCode)
    }
}

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("Download completed!");
        });
    } else {
        console.error(`Download failed. Server responded with code: ${response.statusCode}`);
    }
}).on('error', (err) => {
    console.error("Error during download:", err.message);
});

browser.js

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"; // Specify the name of the downloaded object.

fetch(fileURL)
    .then(response => {
        if (!response.ok) {
            throw new Error(`Server replied HTTP code: ${response.status}`);
        }
        return response.blob(); // Change the type of the response to blob.
    })
    .then(blob => {
        const link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download=savePath; // Specify the name of the downloaded object.
        document.body.appendChild(link); // This step ensures that the presigned URL exists in the document.
        link.click(); // Click the presigned URL to simulate the object download.
        link.remove(); // Remove the presigned URL after the object is downloaded.
        console.log("Download completed!");
    })
    .catch(error => {
        console.error("Error during download:", error);
    });

Android

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"; // Specify the path in which you want to store the downloaded object.
        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();
        }
    }
}

iOS

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // Specify the presigned URL and the path in which you want to store the object.
        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"; // Replace your_username with your username.
        
        // Create a URL object.
        NSURL *url = [NSURL URLWithString:fileURL];
        
        // Create an object download task.
        NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            // Handle errors.
            if (error) {
                NSLog(@"Error during download: %@", error.localizedDescription);
                return;
            }
            
            // Check the data in the object.
            if (!data) {
                NSLog(@"No data received.");
                return;
            }
            
            // Save the object.
            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);
            }
        }];
        
        // Start the object download task.
        [task resume];
        
        // Continue to run the main thread to complete the asynchronous request.
        [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}

Other scenarios

Generate a presigned URL that allows HTTP GET requests for a specific version of an object

This scenario applies to users who have enabled versioning.

The following sample code generates a presigned URL that allows HTTP GET requests for a specific version of an object, allowing third parties to download historical versions of objects.

Java

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import java.net.URL;
import java.util.*;
import java.util.Date;

public class Demo {
    public static void main(String[] args) throws Throwable {
        // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
		    // Specify the name of the bucket. Example: examplebucket. 
        String bucketName = "examplebucket";
        // Specify the full path of the object. Example: exampleobject.txt. Do not include the bucket name in the full path of the object. 
        String objectName = "exampleobject.txt";
        // Specify the version ID of the object. 
        String versionId = "CAEQARiBgID8rumR2hYiIGUyOTAyZGY2MzU5MjQ5ZjlhYzQzZjNlYTAyZDE3****";
        // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. 
        String region = "cn-hangzhou";

        // Create an OSSClient instance. 
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // Create a request. 
            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectName);
            // Set HttpMethod to GET. 
            generatePresignedUrlRequest.setMethod(HttpMethod.GET);
            // Specify the validity period of the presigned URL. Unit: milliseconds. In this example, the validity period is 1 hour. 
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
            generatePresignedUrlRequest.setExpiration(expiration);
            // Specify the version ID of the object. 
            Map<String, String> queryParam = new HashMap<String, String>();
            queryParam.put("versionId", versionId);
            generatePresignedUrlRequest.setQueryParameter(queryParam);
            // Generate a presigned URL. 
            URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
            System.out.println(url);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

Python

import argparse
import alibabacloud_oss_v2 as oss

# Create a command-line parameter parser and describe the purpose of the script.
parser = argparse.ArgumentParser(description="presign get object sample")

# Specify the --region parameter, which specifies the region in which the bucket is located. This command line parameter is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Specify the --bucket parameter to indicate the name of the bucket in which the object is stored. This parameter is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Specify the --endpoint parameter, which specifies the endpoint that other services can use to access OSS. This command line parameter is optional.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Specify the --key parameter, which specifies the name of the object. This command line parameter is required.
parser.add_argument('--key', help='The name of the object.', required=True)

def main():
    # Parse the command line parameters to obtain the values specified by the user.
    args = parser.parse_args()

    # From the environment variables, load the authentication information required to access OSS.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Use the default configurations of the SDK to create a configuration object and specify the credential provider.
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    
    # Specify the region attribute of the configuration object based on the command line parameters provided by the user.
    cfg.region = args.region

    # If a custom endpoint is provided, update the endpoint attribute of the cfg object with the provided endpoint.
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # Use the preceding configuration to initialize the OSSClient instance and allow the instance to interact with OSS.
    client = oss.Client(cfg)

    # Initiate a request to generate a presigned URL.
    # The version_id parameter is optional. You need to specify this parameter only when the object is versioned.
    pre_result = client.presign(
        oss.GetObjectRequest(
            bucket=args.bucket,  # Specify the bucket name.
            key=args.key,        # Specify the object key.
            version_id='yourVersionId'  # If applicable, specify the version ID of the object.
        )
    )

    # Display the HTTP method, expiration time, and presigned URL.
    print(f'method: {pre_result.method},'
          f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
          f' url: {pre_result.url}'
    )

    # Display the signed headers.
    for key, value in pre_result.signed_headers.items():
        print(f'signed headers key: {key}, signed headers value: {value}')

# Call the main function to start the processing logic when the script is directly run.
if __name__ == "__main__":
    main()  # Script entry point, program flow starts here

Go

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"
)

// Specify the global variables.
var (
	region: string; // The region in which the bucket is located.
	bucketName string // The name of the bucket.
	objectName string // The name of the object.
)

// Specify the init function used to initialize command line parameters.
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() {
	// Parse command line parameters.
	flag.Parse()

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// Load the default configurations and specify the credential provider and region.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Generate a presigned URL for the GetObject request.
	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
		Bucket:    oss.Ptr(bucketName),
		Key:       oss.Ptr(objectName),
		VersionId: oss.Ptr("yourVersionId"), // Specify the version 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)
}

Node.js

const OSS = require("ali-oss");

const client = await new OSS({
  // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  bucket: 'examplebucket',
  // Specify the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set the region to oss-cn-hangzhou.
  region: 'oss-cn-hangzhou',
  // Set secure to true and use HTTPS to prevent the generated download link from being blocked by the browser.
  secure: true,
  authorizationV4: true
});


// Generate a presigned URL.
const signedUrl = await client.signatureUrlV4('GET', 3600, {
  queries:{
    // Specify the version ID of the object.
    "versionId":'yourVersionId'
  }
}, 'demo.pdf');

PHP

<?php

// Include the autoload file to load dependencies.
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// Specify descriptions for command line parameters.
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // (Required) Specify the region in which the bucket is located.
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // (Optional) Specify the endpoint for accessing OSS.
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // (Required) Specify the name of the bucket.
    "key" => ['help' => 'The name of the object', 'required' => True], // (Required) Specify the name of the object.
];

// Convert the descriptions to a list of long options required by getopt.
// Add a colon (:) to the end of each parameter to indicate that a value is required.
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// Parse the command line parameters.
$options = getopt("", $longopts);

// Check whether the required parameters are configured.
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // Get the help information for the parameter.
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // If the required parameters are not configured, exit the program.
    }
}

// Obtain values from the parsed parameters.
$region = $options["region"]; // The region in which the bucket is located.
$bucket = $options["bucket"]; // The name of the bucket.
$key = $options["key"];       // The name of the object.

// Load access credentials from environment variables.
// Use EnvironmentVariableCredentialsProvider to retrieve the AccessKey ID and AccessKey secret from environment variables.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// Use the default configuration of the SDK.
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // Set the credential provider.
$cfg->setRegion($region); // Set the region in which the bucket is located.
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // If an endpoint is provided, set the endpoint.
}

// Create an OSSClient instance.
$client = new Oss\Client($cfg);

$versionId = "yourVersionId"; // Version number, this is just an example value, please replace with the actual version ID when using.

// Create a GetObjectRequest object for downloading the object.
$request = new Oss\Models\GetObjectRequest(bucket:$bucket, key:$key, versionId: $versionId);

// Call the presign method to generate a presigned URL.
$result = $client->presign($request);

// Print the presigned result.
// Output the presigned URL, which users can directly use for download operations.
print(
    'get object presign result:' . var_export($result, true) . PHP_EOL . // Detailed information about the presigned result.
    'get object url:' . $result->url . PHP_EOL                           // Presigned URL for directly downloading the object.
);

Generate a presigned URL for preview using a custom domain name

If you want the generated presigned URL to support online preview, you must map a custom domain name to the bucket.

Use the OSS console

  1. Log on to the OSS console.

  2. In the left-side navigation pane, click Buckets. On the Buckets page, click the name of the bucket.

  3. In the left-side navigation tree, choose Object Management > Objects.

  4. On the Objects page, click the name of the object.

  5. In the View Details panel, select the custom domain name that is mapped to the bucket in the Custom Domain Name field, retain the default settings for other parameters, and then click Copy Object URL.

    2.png

Use ossbrowser

You can use ossbrowser to perform the same object-level operations that you can perform in the OSS console. You can follow the on-screen instructions in ossbrowser to obtain a presigned URL. For information about how to download ossbrowser, see ossbrowser 1.0.

  1. Use the custom domain name to log on to ossbrowser.

  1. Obtain the URL of the object.

Use OSS SDKs

You can use the custom domain name to create an OssClient instance and generate a presigned URL.

Java
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;

import java.net.URL;
import java.util.Date;

public class Demo {
    public static void main(String[] args) throws Throwable {
        // Specify a custom domain name. Example: https://static.example.com. 
        String endpoint = "yourCustomEndpoint";
        // Specify the region in which the bucket is located. Example: cn-hangzhou.
        String region = "cn-hangzhou";

        // Obtain access credentials from environment variables. Before you run the sample code, you must configure the environment variables.
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // Create an OSSClient instance.
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // To enable CNAME, set this parameter to true.
        clientBuilderConfiguration.setSupportCname(true);
        // Explicitly declare the use of the V4 signature algorithm.
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            // Specify the validity period of the presigned URL. Unit: milliseconds. In this example, the validity period is 1 hour. 
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
            // Generate a presigned URL that allows HTTP GET requests. In this example, no additional request headers are specified. Other users can access the relevant content directly by using the browser. 
            String bucketName = "examplebucket";
            String objectName = "demo.png";
            URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
            System.out.println(url);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
Python
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4.
region = "cn-hangzhou"

# Specify the custom domain name. Example: static.example.com.
endpoint = 'http://static.example.com'

# Specify the name of your bucket.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region, is_cname=True)


# Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt.
object_name = 'exampledir/exampleobject.txt'

# Generate a presigned URL that is used to download the object. In this example, the validity period of the URL is 600 seconds.
# By default, OSS identifies forward slashes (/) in the full path of an object as escape characters in the signing process. Therefore, the presigned URL cannot be directly used.
# Set the slash_safe parameter to True. This way, OSS does not identify the forward slashes (/) in the full path of the object as escape characters, and the presigned URL can be directly used.
url = bucket.sign_url('GET', object_name, 600, slash_safe=True, params=params)
print('Presigned URL:', url)
Node.js
const OSS = require("ali-oss");

// Specify a function used to generate a presigned URL.
async function generateSignatureUrl(fileName) {
  // Obtain the presigned URL.
  const client = await new OSS({
      // Specify the custom domain name that you want to map to the bucket.
      endpoint: 'http://static.example.com', 
      // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
      accessKeyId: process.env.OSS_ACCESS_KEY_ID,
      accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
      bucket: 'examplebucket',
      // Specify the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set the region to oss-cn-hangzhou.
      region: 'oss-cn-hangzhou',
      authorizationV4: true,
      cname: true
  });

  return await client.signatureUrlV4('GET', 3600, {
      headers: {} // Specify the request headers based on the actual request headers.
  }, fileName);
}
// Call the function and pass in the name of the object.
generateSignatureUrl('yourFileName').then(url => {
  console.log('Generated Signature URL:', url);
}).catch(err => {
  console.error('Error generating signature URL:', err);
});
PHP
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Http\RequestCore;
use OSS\Http\ResponseCore;
use OSS\Credentials\EnvironmentVariableCredentialsProvider;

// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
$provider = new EnvironmentVariableCredentialsProvider();
// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to http://static.example.com.
$endpoint = "http://static.example.com";
// Specify the name of the bucket.
$bucket= "examplebucket";
// Specify the full path of the object. Do not include the bucket name in the full path.
$object = "exampleobject.txt";
// Set the validity period of the presigned URL to 600 seconds. Maximum value: 32400.
$timeout = 600;
try {
    $config = array(  
        "provider" => $provider,
        "endpoint" => $endpoint,
        'signatureVersion'=>OssClient::OSS_SIGNATURE_VERSION_V4,
        "cname"	=> true,
        "region"=> "cn-hangzhou"
    );
    $ossClient = new OssClient($config);
    // Generate a presigned URL.
    $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "GET");
    print_r($signedUrl);
} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
Go
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"
)

// Specify the global variables.
var (
	region     string // Region in which the bucket is located.
	bucketName string // Name of the bucket.
	objectName string // Name of the object.
)

// Specify the init function used to initialize command line parameters.
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() {
	// Parse command line parameters.
	flag.Parse()

	// Check whether the name of the bucket is specified.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is specified.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the object is specified.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// Load the default configurations and specify the credential provider and region.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region).
		WithEndpoint("http://static.example.com").
		WithUseCName(true)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Generate a presigned URL for the GetObject request.
	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
		Bucket: oss.Ptr(bucketName),
		Key:    oss.Ptr(objectName),
		//RequestPayer: oss.Ptr("requester"), // Specify the identity of the 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 {
		// If you specify request headers when you generate a presigned URL that allows HTTP GET requests, make sure that the request headers are included in the GET request initiated by using the presigned URL. This prevents request failures and signature errors.
		log.Printf("signed headers:\n")
		for k, v := range result.SignedHeaders {
			log.Printf("%v: %v\n", k, v)
		}
	}
}

Use ossutil

Use the custom domain name to generate a presigned URL for an object by running the presign command.

ossutil presign oss://examplebucket/exampleobject.txt --endpoint "http://static.example.com” --addressing-style "cname"

To enable the ossutil command to automatically use a custom domain name, instead of manually specifying it each time, add the custom domain name to the configuration file.

Generate a pre-signed URL for forced download

This scenario applies to users who want to change the default access behavior of a presigned URL from preview (possibly because a custom domain name is used or the OSS service was activated before 00:00 on October 9, 2022) to forced download.

The following examples show how to set forced download when using a custom domain name and allow customization of the file name during download. The same applies to the default OSS domain name.

Java

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;

import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;

public class Demo {
    public static void main(String[] args) throws Throwable {
        //  Specify a custom domain name. Example: https://static.example.com. 
        String endpoint = "http://static.example.com";
        // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // Specify the name of the bucket. Example: examplebucket. 
        String bucketName = "examplebucket";
        // Specify the full path of the object. Example: exampleobject.txt. Do not include the bucket name in the full path of the object. 
        String objectName = "exampleobject.txt";

        // Create an OSSClient instance. 
        String region = "cn-hangzhou";
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // Note that if you use a custom domain name, you must set CNAME to true. 
        clientBuilderConfiguration.setSupportCname(true);

        // Explicitly declare the use of the V4 signature algorithm.
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        URL signedUrl = null;
        try {
            // Specify the validity period of the presigned URL. Unit: milliseconds. In this example, the validity period is 1 hour. 
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L);

            // Specify the name of the object that you want to forcibly download. Example: homework.txt. 
            String filename = "homework.txt";

            // Generate a presigned URL. 
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);

            // Specify that the object is forcibly downloaded and specify the name of the downloaded object.
            request.getResponseHeaders().setContentDisposition("attachment;filename=" + URLEncoder.encode(filename,"UTF-8"));

            // Set the validity period of the request. 
            request.setExpiration(expiration);

            // Generate the presigned URL that allows HTTP GET requests. 
            signedUrl = ossClient.generatePresignedUrl(request);
            // Display the presigned URL. 
            System.out.println("signed url for putObject: " + signedUrl);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        }
    }

}

Python

import argparse
import alibabacloud_oss_v2 as oss

# Create a command-line parameter parser and describe the purpose of the script.
parser = argparse.ArgumentParser(description="presign get object sample")

# Specify the --region parameter, which specifies the region in which the bucket is located. This parameter is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Specify the --bucket parameter to indicate the name of the bucket in which the object is stored. This parameter is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Specify the --endpoint parameter, which specifies the endpoint that other services can use to access OSS. This parameter is optional.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Specify the --key parameter, which specifies the name of the object. This parameter is required.
parser.add_argument('--key', help='The name of the object.', required=True)

def main():
    # Parse the command-line arguments.
    args = parser.parse_args()

    # Obtain access credentials from environment variables for authentication.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Use the default configuration to create a configuration object and specify the credential provider.
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider

    # Set the region attribute of the cfg object to the region provided in the command line.
    cfg.region = args.region

    # If a custom endpoint is provided, update the endpoint attribute of the cfg object with the provided endpoint.
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # Use the preceding configuration to initialize the OSSClient instance and allow the instance to interact with OSS.
    client = oss.Client(cfg)

    # Initiate a request to generate a presigned URL.
    pre_result = client.presign(
        oss.GetObjectRequest(
            bucket=args.bucket,  # Specify the bucket name.
            key=args.key,        # Specify the object key.
            response_content_disposition="attachment;filename=test.txt",
        )
    )

    # Display the HTTP method, expiration time, and presigned URL.
    print(f'method: {pre_result.method},'
          f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
          f' url: {pre_result.url}'
    )

    # Display the signed headers.
    for key, value in pre_result.signed_headers.items():
        print(f'signed headers key: {key}, signed headers value: {value}')

# Call the main function to start the processing logic when the script is directly run.
if __name__ == "__main__":
    main()  # Script entry point, program flow starts here

Go

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"
)

// Specify the global variables.
var (
	region     string // The region in which the bucket is located.
	bucketName string // The name of the bucket.
	objectName string // The name of the object.
)

// Specify the init function used to initialize command line parameters.
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() {
	// Parse the command line parameters.
	flag.Parse()

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// Load the default configurations and specify the credential provider and region.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Generate a signed URL for the GetObject request.
	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("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 {
		//If you specify request headers when you generate a signed URL that allows HTTP GET requests, make sure that the request headers are included in the GET request initiated by using the signed URL.
		log.Printf("signed headers:\n")
		for k, v := range result.SignedHeaders {
			log.Printf("%v: %v\n", k, v)
		}
	}
}

Generate multiple presigned URLs at a time

Note
  • The OSS console allows you to export a list of presigned URLs for objects in the current directory, but not for those in subdirectories of the current directory. To generate a list of presigned URLs for objects in the current directory and its subdirectories, you can use ossutil.

  • If you want to use an SDK to generate multiple presigned URLs, you can use the GetBucket (ListObjects) operation to obtain the names of all objects, and then generate a presigned URL for each object.

Use the OSS console

  1. Select the target objects, and then click Export URL List below.list

  2. In the Export URL List panel, configure the following parameters:

    Parameter

    Description

    Use HTTPS

    By default, the URLs of objects are generated using HTTPS. If you want to use HTTP to generate the URLs of objects, turn off Use HTTPS.

    Validity Period

    If the ACL of the objects that you want to share is private, you must set a validity period for the URLs of the objects.

    Valid values: 60 to 32400.

    Unit: seconds.

    Custom Domain Name

    If you want to ensure that an image or webpage object is previewed instead of being downloaded when it is accessed by using a URL, use the custom domain name that is mapped to the bucket.

    You can configure this parameter only after you map a custom domain name to the bucket.

    Accelerate Endpoint

    If third parties located far from your data centers need to access the objects, we recommend that you use the acceleration endpoint of the bucket to generate the URLs of the objects.

    You can configure this parameter only after you enable transfer acceleration for the bucket.

  3. Click OK, and then save the URL list file to your computer.

Use ossutil

  • For objects in the "folder" directory in the examplebucket bucket, generate presigned URLs that have a validity period of 15 minutes.

    ossutil presign oss://examplebucket/folder/ -r
  • For TXT objects in the "folder" directory of the examplebucket bucket, generate URLs that have the default validity period of 15 minutes.

    ossutil presign oss://examplebucket/folder/ -r --include "*.txt"
  • For all objects in the examplebucket bucket, generate signed URLs that have the default validity period of 15 minutes.

    ossutil presign oss://examplebucket/ -r

For more information about how to use ossutil to generate presigned URLs, see presign.

Learn more

What is a presigned URL

A presigned URL is a URL that includes signature data and expiration information and thereby provides secure, temporary access to OSS objects. When generating a presigned URL, the local system uses the AccessKey pair to encrypt parameters such as the resource path and expiration time, generates signature parameters, and adds them to the URL to form a complete presigned URL. The typical format is: https://BucketName.Endpoint/Object?signature parameters.

When an object is requested using the presigned URL, OSS verifies the signature information. If the URL has inconsistent parameter settings or has expired, the request will be denied. Below is an example of a presigned URL.

https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-process=image%2Fresize%2Cp_10&x-oss-date=20241115T095058Z&x-oss-expires=3600&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************%2F20241115%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=6e7a*********************************

Presigned URLs enable object owners to provide secure and time-limited access to OSS objects without exposing their access credentials.

Scenarios

  • Short-term file sharing: When a third party requests access to a specific file, the backend generates a presigned URL with an expiration time and returns it to the frontend. The frontend provides this URL to the third party, who can securely upload or download the file within the validity period of the link.

  • Flexible access: Object owners can share presigned URLs through email or chat tools. Third parties can download files by pasting the URL into their browser address bar.

FAQ

How do I obtain a long-term URL without a signature?

To create an object URL that does not contain an expiration time or signature information, you must first make sure that the object is publicly accessible. You can make an OSS object publicly accessible by using two methods:

Warning

Making an object publicly accessible allows all Internet users to access the object. This can cause data leaks and unexpected costs. We recommend that you use a presigned URL that includes signature information and an expiration time.

  1. Set Object ACL: Set the permission of the OSS object to public-read. This makes the URL of the object permanently accessible to anyone. To prevent unauthorized access to your objects from other websites, you need to configure hotlink protection in OSS.

    • If you use the default domain name of OSS, the format of the object URL is https://BucketName.Endpoint/ObjectName. In the preceding URL, ObjectName represents the full path of the object, including the file extension. For more information about endpoints in different regions, see OSS regions and endpoints.

      For example, an object named example.jpg is stored in the "example" directory of a bucket named examplebucket in the China (Hangzhou) region. Object URLs:
      Internet URL: https://examplebucket.oss-cn-hangzhou.aliyuncs.com/example/example.jpg
      Internal URL (for access from ECS instances in the same region): https://examplebucket.oss-cn-hangzhou-internal.aliyuncs.com/example/example.jpg
    • If your bucket is attached to a custom domain name, the format of the object URL is https://YourDomainName/ObjectName. For more information, see Map custom domain names to OSS endpoints.

      For example, if you attach a custom domain name example.com to a bucket named examplebucket in the China (Hangzhou) region, and the bucket contains a file named example.jpg, the URL of the file is https://example.com/example.jpg.
  1. Accelerate OSS resources with CDN: Keep the permission of the OSS object as private and provide public read access through CDN. The object URL is permanently accessible to anyone. You can access OSS resources by using the CDN-accelerated domain name and the object URL. To prevent unauthorized access to your objects from other websites, we recommend that you configure a Referer blacklist or whitelist in CDN.

    For example, if the CDN-accelerated domain name is aliyundoc.com and you want to access a file named image_01.jpg in the root directory, the URL of the file is http://aliyundoc.com/image_01.jpg.

Can I allow only specific websites to access OSS resources and reject requests from other sources?

Yes, you can do so by configuring hotlink protection settings for the bucket. Specifically, you need to include the websites in a Referer whitelist to authorize them to access your objects. This allows object requests from the specified websites and prevents unauthorized websites from linking to your OSS objects. For detailed configuration steps, see Configure hotlink protection to prevent unauthorized access from other websites.

How do I authorize third parties to perform more operations on OSS resources beyond downloads?

To allow users to perform more operations in addition to downloads, you can use STS tokens to authorize flexible, temporary access. If you want third parties to perform more operations on OSS resources, such as listing objects or copying objects, rather than just downloading objects, we recommend that you learn about and use STS temporary access credentials. For more information, see Use STS to authorize temporary access to OSS.

How do I customize the file name when downloading?

Yes, you can use the response-content-disposition parameter in a presigned URL to specify the file name for a single download request, or modify the Content-Disposition metadata of the file to specify the file name for all download requests. For more information, see Customize the file name when downloading OSS objects.

How to process images using signed URLs?

To use a presigned URL for image processing operations, such as resizing and watermarking, include image processing parameters when you generate the presigned URL. For more information, see Process images by using object URLs.