Objects in an Object Storage Service (OSS) bucket are private by default. Use the Go software development kit (SDK) to generate a signed URL for a GET request, then share the URL so others can download the object without needing OSS credentials. The URL is reusable until it expires, after which you must generate a new one.
Prerequisites
Before you begin, ensure that you have:
An OSS bucket with at least one object to download
The
oss:GetObjectRAM permission on the target object (required to allow downloads via the signed URL; no special permission is needed to generate the URL itself)The
OSS_ACCESS_KEY_IDandOSS_ACCESS_KEY_SECRETenvironment variables configured. See Configure access credentials (Go SDK V1)(Optional) An OSSClient instance initialized with a custom domain name or Security Token Service (STS). See Configuration examples for common scenarios
The examples in this topic use the public endpoint for the China (Hangzhou) region. To access OSS from another Alibaba Cloud service in the same region, use the internal endpoint instead. For a full list of regions and endpoints, see Regions and endpoints.
How it works
The object owner initializes an OSSClient with V4 signing enabled.
The owner calls
bucket.SignURLto generate a signed URL for an HTTP GET request, with a specified expiry in seconds.The signed URL is shared with any user who needs to download the object.
The recipient sends a GET request to the signed URL — no OSS credentials required.
OSS validates the signature and returns the object if the URL is still within its validity period.
The maximum validity period for a V4 signed URL is 7 days (604,800 seconds). See Signature V4 (recommended).
Download using the signed URL
Share the signed URL with any user. They can download the object using any HTTP client — no OSS credentials required.
All examples below use the same signed URL format. Replace the example URL with the one generated by your Go code.
curl
curl -SO "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"Java
<details> <summary>Java example</summary>
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) {
// Replace with the signed URL generated by your Go code.
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******************************************************";
// Replace with the local path where you want to save the object.
String savePath = "C:/downloads/myfile.txt";
try {
downloadFile(fileURL, savePath);
System.out.println("Download completed!");
} catch (IOException e) {
System.err.println("Error during download: " + e.getMessage());
}
}
private static void downloadFile(String fileURL, String savePath) throws IOException {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
FileOutputStream outputStream = new FileOutputStream(savePath);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
httpConn.disconnect();
}
}</details>
Node.js
<details> <summary>Node.js example</summary>
const https = require('https');
const fs = require('fs');
// Replace with the signed URL generated by your Go code.
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******************************************************";
// Replace with the local path where you want to save the object.
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);
});</details>
Python
<details> <summary>Python example</summary>
import requests
# Replace with the signed URL generated by your Go code.
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******************************************************"
# Replace with the local path where you want to save the object.
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)</details>
Go
<details> <summary>Go example</summary>
package main
import (
"io"
"net/http"
"os"
)
func main() {
// Replace with the signed URL generated by your Go code.
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******************************************************"
// Replace with the local path where you want to save the object.
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)
}
}</details>
JavaScript
<details> <summary>JavaScript example</summary>
// Replace with the signed URL generated by your Go code.
const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
const savePath = "C:/downloads/myfile.txt";
fetch(fileURL)
.then(response => {
if (!response.ok) {
throw new Error(`Server replied HTTP code: ${response.status}`);
}
return response.blob();
})
.then(blob => {
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = savePath;
document.body.appendChild(link);
link.click();
link.remove();
console.log("Download completed!");
})
.catch(error => {
console.error("Error during download:", error);
});</details>
Android (Java)
<details> <summary>Android (Java) example</summary>
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];
// Saves the object to the device's Downloads directory.
String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/myfile.txt";
try {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
FileOutputStream outputStream = new FileOutputStream(savePath);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
return "Download completed!";
} else {
return "No file to download. Server replied HTTP code: " + responseCode;
}
} catch (Exception e) {
return "Error during download: " + e.getMessage();
}
}
}</details>
Objective-C
<details> <summary>Objective-C example</summary>
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Replace with the signed URL generated by your Go code.
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******************************************************";
// Replace your_username with your macOS username.
NSString *savePath = @"/Users/your_username/Desktop/myfile.txt";
NSURL *url = [NSURL URLWithString:fileURL];
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Error during download: %@", error.localizedDescription);
return;
}
if (!data) {
NSLog(@"No data received.");
return;
}
NSError *writeError = nil;
BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath] options:NSDataWritingAtomic error:&writeError];
if (success) {
NSLog(@"Download completed!");
} else {
NSLog(@"Error saving file: %@", writeError.localizedDescription);
}
}];
[task resume];
[[NSRunLoop currentRunLoop] run];
}
return 0;
}</details>
Other scenarios
Download a specific object version
To download a specific version of an object, pass oss.VersionId as an option when calling SignURL. The generated URL lets the recipient download that exact version.
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Printf("Error: %v", err)
}
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("cn-hangzhou"))
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Printf("Error: %v", err)
}
bucketName := "examplebucket"
// Replace with the full object path (excluding the bucket name).
objectName := "exampledir/exampleobject.txt"
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Printf("Error: %v", err)
}
// Replace with the version ID of the object to download.
options := []oss.Option{
oss.VersionId("CAEQEhiBgIDmgPf8mxgiIDA1YjZlNDIxY2ZmMzQ1MmU5MTM1Y2M4Yzk4******"),
}
// Generate a signed URL valid for 600 seconds (10 minutes).
signedURL, err := bucket.SignURL(objectName, oss.HTTPGet, 600, options...)
if err != nil {
log.Printf("Error: %v", err)
}
log.Printf("Signed URL: %s\n", signedURL)
}What's next
For the complete sample code, see the GitHub example.
For the full API reference, see SignURL.
To generate a signed URL for uploading an object, see Upload an object by using a signed URL (Go SDK V1).
For more information about Resource Access Management (RAM) policies for OSS, see Common examples of RAM policies.