A presigned URL grants time-limited, unauthenticated access to a private OSS object. Anyone with the URL can download the object via HTTP GET — no OSS credentials required — until the URL expires. Use the presign method in OSS SDK for Python V2 to generate these URLs.
Prerequisites
Before you begin, ensure that you have:
An OSS bucket with at least one object to share
The
oss:GetObjectpermission on the object (required to allow recipients to download via the presigned URL)OSS SDK for Python V2 installed and credentials configured via environment variables
Generating a presigned URL requires no specific permissions. The oss:GetObject permission is what allows the URL recipient to download the object. For more information, see Common examples of RAM policies.
How it works
The object owner calls
client.presign()with aGetObjectRequestto generate a presigned URL.OSS signs the URL using the V4 signature algorithm and embeds the expiration time as a query parameter.
The URL recipient makes a standard HTTP GET request to download the object — no authentication headers needed.
OSS validates the signature and expiration at request time. If valid, it returns the object.
Generate a presigned URL
The following example wraps the presign call in a reusable function. Call it with your bucket name, object key, and desired validity period to get a presigned download URL.
import datetime
import alibabacloud_oss_v2 as oss
def generate_presigned_download_url(
region: str,
bucket: str,
key: str,
expires_in: datetime.timedelta = datetime.timedelta(hours=1),
) -> str:
"""Generate a presigned URL for downloading an OSS object via HTTP GET.
Args:
region: The region where the bucket is located, e.g., "cn-hangzhou".
bucket: The bucket name.
key: The object key (path) within the bucket.
expires_in: How long the URL remains valid. Defaults to 1 hour.
Maximum validity with V4 signatures is 7 days.
Returns:
A presigned URL string. Anyone with this URL can download the object
until it expires.
"""
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
cfg = oss.config.load_default()
cfg.credentials_provider = credentials_provider
cfg.region = region
client = oss.Client(cfg)
result = client.presign(
oss.GetObjectRequest(bucket=bucket, key=key),
expires=expires_in,
)
return result.url
if __name__ == "__main__":
url = generate_presigned_download_url(
region="cn-hangzhou",
bucket="examplebucket",
key="exampleobject.txt",
expires_in=datetime.timedelta(hours=1),
)
print(f"Presigned URL: {url}")With the V4 signature algorithm, the maximum validity period is 7 days. If you specify both expiration (absolute datetime) and expires (relative timedelta), expiration takes precedence.
presign method reference
Syntax
presign(request: GetObjectRequest, **kwargs) -> PresignResultParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
request | GetObjectRequest | Yes | Specifies the operation the presigned URL supports. See Client.presign. |
expires | datetime.timedelta | No | Validity period relative to the current time. Default: 15 minutes. |
expiration | datetime.datetime | No | Absolute expiration datetime. Takes precedence over expires if both are set. |
Return value: `PresignResult`
| Field | Type | Description |
|---|---|---|
method | str | HTTP method corresponding to the request operation (GET for GetObject). |
url | str | The presigned URL. |
expiration | datetime | When the URL expires. |
signed_headers | MutableMapping | Request headers that were signed. Include these headers in the download request if present. |
For full API details, see PresignResult.
Use the presigned URL
The presigned URL is a standard HTTP GET endpoint — no additional authentication headers are needed. Use it with any HTTP client, in any language, or directly in a browser.
The following examples all use the same presigned URL structure:
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******************************************************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******************************************************"Python
import requests
def download_with_presigned_url(presigned_url: str, save_path: str) -> None:
response = requests.get(presigned_url, stream=True)
if response.status_code == 200:
with open(save_path, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
print("Download completed.")
else:
print(f"Download failed. HTTP {response.status_code}")
print(response.text)
download_with_presigned_url(
presigned_url="<presigned-url>",
save_path="/path/to/save/exampleobject.txt",
)Java
import java.io.*;
import java.net.*;
public class PresignedDownload {
public static void main(String[] args) throws IOException {
String fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
String savePath = "C:/downloads/myfile.txt";
URL url = new URL(fileURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
try (InputStream in = new BufferedInputStream(conn.getInputStream());
FileOutputStream out = new FileOutputStream(savePath)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
System.out.println("Download completed.");
}
} else {
System.out.println("Download failed. HTTP " + conn.getResponseCode());
}
conn.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 = "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. HTTP ${response.statusCode}`);
}
}).on("error", (err) => {
console.error("Error:", err.message);
});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 := "myfile.txt"
resp, err := http.Get(fileURL)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
out, err := os.Create(savePath)
if err != nil {
panic(err)
}
defer out.Close()
io.Copy(out, resp.Body)
println("Download completed.")
} else {
println("Download failed. HTTP", resp.StatusCode)
}
}JavaScript (browser)
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******************************************************";
fetch(fileURL)
.then((response) => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.blob();
})
.then((blob) => {
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = "exampleobject.txt";
document.body.appendChild(link);
link.click();
link.remove();
})
.catch((err) => console.error("Error:", err));Android (Java)
import android.os.*;
import java.io.*;
import java.net.*;
public class DownloadTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
String fileURL = params[0];
String savePath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS) + "/myfile.txt";
try {
URL url = new URL(fileURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
try (InputStream in = new BufferedInputStream(conn.getInputStream());
FileOutputStream out = new FileOutputStream(savePath)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return "Download completed.";
}
return "HTTP " + conn.getResponseCode();
} catch (Exception e) {
return "Error: " + e.getMessage();
}
}
}Objective-C
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
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>/Downloads/myfile.txt";
NSURL *url = [NSURL URLWithString:fileURL];
NSURLSessionDataTask *task = [[NSURLSession sharedSession]
dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Error: %@", error.localizedDescription);
return;
}
if (!data) {
NSLog(@"No data received.");
return;
}
NSError *writeError = nil;
BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath]
options:NSDataWritingAtomic
error:&writeError];
NSLog(success ? @"Download completed." : @"Save error: %@", writeError.localizedDescription);
}];
[task resume];
[[NSRunLoop currentRunLoop] run];
}
return 0;
}Treat presigned URLs as bearer tokens. Anyone with the URL can download the object until it expires. Share URLs only with intended recipients and use short expiration times for sensitive objects.
Common scenarios
What's next
For the complete sample code, see presigner_get_object.py on GitHub.
For signature algorithm details, see (Recommended) Include a V4 signature in a URL.
For region IDs and endpoint formats, see Regions and endpoints.