Par défaut, la liste de contrôle d'accès (ACL) d'un objet dans un compartiment Object Storage Service (OSS) est privée. Seul le propriétaire de l'objet dispose des autorisations nécessaires pour y accéder. Cette rubrique explique comment utiliser OSS SDK for Python pour générer une URL pré-signée permettant à un utilisateur de télécharger un objet spécifique via la méthode HTTP GET pendant une période donnée. Tant que l'URL est valide, l'utilisateur peut accéder à l'objet à plusieurs reprises. Si l'URL expire, générez-en une nouvelle pour prolonger l'accès de l'utilisateur.
Remarques sur l'utilisation
L'exemple de code de cette rubrique utilise l'ID de région
cn-hangzhoude la région Chine (Hangzhou). Par défaut, le point de terminaison public permet d'accéder aux ressources d'un compartiment. Pour accéder aux ressources du compartiment depuis d'autres services Alibaba Cloud situés dans la même région, utilisez le point de terminaison interne. Pour plus d'informations sur les régions et les points de terminaison OSS, consultez Régions et points de terminaison.Aucune autorisation n'est requise pour générer une URL pré-signée. Toutefois, pour qu'un tiers puisse télécharger l'objet à l'aide de cette URL, l'utilisateur qui la génère doit disposer de l'autorisation
oss:GetObject. Pour savoir comment accorder des autorisations, consultez Accorder des autorisations personnalisées à un utilisateur RAM.Cette rubrique utilise l'algorithme de signature V4 pour générer des URL pré-signées valides jusqu'à 7 jours. Pour plus d'informations, consultez (Recommandé) Signatures V4 dans les URL pré-signées.
Procédure
La procédure suivante décrit comment télécharger un objet à l'aide d'une URL pré-signée :
Définition de la méthode
Appelez la méthode presign pour générer une URL pré-signée accordant un accès temporaire à un objet OSS. L'URL pré-signée reste utilisable plusieurs fois avant son expiration.
La syntaxe de la méthode presign est la suivante :
presign(request: GetObjectRequest, **kwargs) → PresignResult
Paramètres de requête
|
Paramètre |
Type |
Description |
|
request |
GetObjectRequest |
L'opération API que l'URL pré-signée doit prendre en charge. Pour plus d'informations, consultez Client.presign. |
|
expires |
datetime.timedelta |
La durée de validité de l'URL pré-signée à partir de l'heure actuelle. Il s'agit d'un paramètre facultatif. Par exemple, pour définir une validité de 30 minutes, attribuez la valeur |
|
expiration |
datetime.datetime |
La date et l'heure d'expiration absolues de l'URL pré-signée. Il s'agit d'un paramètre facultatif. |
Si vous utilisez l'algorithme de signature V4, la durée de validité peut atteindre sept jours. Si vous spécifiez à la fois expiration et expires, le paramètre expiration est prioritaire.
Paramètres de réponse
|
Type |
Description |
|
PresignResult |
Les résultats renvoyés, incluant l'URL pré-signée, la méthode HTTP, l'heure d'expiration et les en-têtes de requête spécifiés dans la demande. Pour plus d'informations, consultez PresignResult. |
Contenu de PresignResult
|
Paramètre |
Type |
Description |
|
method |
str |
La méthode HTTP, qui correspond à l'opération API spécifiée dans la demande de pré-signature. Par exemple, la méthode HTTP de l'opération |
|
url |
str |
L'URL pré-signée. |
|
expiration |
datetime |
L'heure d'expiration de l'URL pré-signée. |
|
signed_headers |
MutableMapping |
Les en-têtes signés spécifiés dans la requête. Par exemple, si |
Pour plus d'informations sur la méthode presign, consultez presign.
Exemple de code
-
Générez une URL pré-signée autorisant les requêtes HTTP GET :
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 to indicate 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 to indicate the endpoint of the region in which the bucket is located. This parameter is optional. parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS') # Specify the --key parameter to indicate 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 parameters to obtain the specified values. args = parser.parse_args() # From the environment variables, load the authentication information required to access OSS. credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider() # Use the default configuration to create a cfg 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 settings to initialize the OSSClient instance. 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() # Specify the entry point of the script. The control flow starts here. -
Utilisez l'URL pré-signée pour télécharger l'objet.
curl
curl -SO "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"Java
import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class Demo { public static void main(String[] args) { // Replace with the generated presigned URL for the GET request. 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******************************************************"; // Enter the destination path to save the file, including the file 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"); // Check the response code. int responseCode = httpConn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // Input stream. InputStream inputStream = new BufferedInputStream(httpConn.getInputStream()); // Output stream. FileOutputStream outputStream = new FileOutputStream(savePath); byte[] buffer = new byte[4096]; // Buffer. int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); inputStream.close(); } else { System.out.println("No file to download. Server replied HTTP code: " + responseCode); } httpConn.disconnect(); } }Node.js
const https = require('https'); const fs = require('fs'); const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=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); });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) } }JavaScript
const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"; const savePath = "C:/downloads/myfile.txt"; // The file name to use for the download. fetch(fileURL) .then(response => { if (!response.ok) { throw new Error(`Server replied HTTP code: ${response.status}`); } return response.blob(); // Convert the response to a blob. }) .then(blob => { const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = savePath; // Set the name of the downloaded file. document.body.appendChild(link); // This step ensures that the link exists in the document. link.click(); // Simulate a click on the download link. link.remove(); // Remove the link after completion. console.log("Download completed!"); }) .catch(error => { console.error("Error during download:", error); });Android-Java
import android.os.AsyncTask; import android.os.Environment; import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class DownloadTask extends AsyncTask<String, String, String> { @Override protected String doInBackground(String... params) { String fileURL = params[0]; String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/myfile.txt"; // The modified save path. try { URL url = new URL(fileURL); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestMethod("GET"); int responseCode = httpConn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { InputStream inputStream = new BufferedInputStream(httpConn.getInputStream()); FileOutputStream outputStream = new FileOutputStream(savePath); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); inputStream.close(); return "Download completed!"; } else { return "No file to download. Server replied HTTP code: " + responseCode; } } catch (Exception e) { return "Error during download: " + e.getMessage(); } } }Objective-C
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { // Define the file URL and save path (change to a valid path). 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 with your username. // Create a URL object. NSURL *url = [NSURL URLWithString:fileURL]; // Create a download task. NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // Error handling. if (error) { NSLog(@"Error during download: %@", error.localizedDescription); return; } // Check the data. if (!data) { NSLog(@"No data received."); return; } // Save the file. 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 task. [task resume]; // Keep the main thread running so that the asynchronous request can be completed. [[NSRunLoop currentRunLoop] run]; } return 0; }
Scénarios courants
Générer une URL pré-signée autorisant les requêtes HTTP GET pour une version spécifique d'un objet
Télécharger un objet à l'aide d'une URL pré-signée contenant des en-têtes de requête spécifiés
Forcer le téléchargement d'un objet à l'aide d'une URL pré-signée
Générer une URL pré-signée permettant le téléchargement d'objets via un point de terminaison personnalisé
Références
Pour obtenir l'exemple de code complet relatif au téléchargement d'un objet à l'aide d'une URL pré-signée, consultez presigner_get_object.py.