All Products
Search
Document Center

Object Storage Service:Upload local files with signed URLs

Last Updated:Mar 11, 2024

Third-party users can use a signed URL to upload a local file without security credentials or authorization. Then, OSS stores the uploaded file as an object in a specific bucket.

Procedure

  1. Generate a signed URL.

    The following sample code provides examples on how to generate a signed URL by using OSS SDKs for common programming languages. For more information about how to generate a signed URL by using OSS SDKs for other programming languages, see Overview.

    Java

    import com.aliyun.oss.*;
    import com.aliyun.oss.common.auth.*;
    import com.aliyun.oss.internal.OSSHeaders;
    import com.aliyun.oss.model.GeneratePresignedUrlRequest;
    import com.aliyun.oss.model.StorageClass;
    import org.apache.http.HttpEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPut;
    import org.apache.http.entity.FileEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import java.io.*;
    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 code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
            EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            // Specify the bucket name. Example: examplebucket. 
            String bucketName = "examplebucket";
            // Specify the full path of the object. Example: exampleobject.txt. The full path cannot contain the bucket name. 
            String objectName = "exampleobject.txt";
    
            // Create an OSSClient instance.
            OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
    
            // Specify request headers. 
            Map<String, String> headers = new HashMap<String, String>();
            /*// Specify the storage class of the object. 
            headers.put(OSSHeaders.STORAGE_CLASS, StorageClass.Standard.toString());
            // Specify ContentType. 
            headers.put(OSSHeaders.CONTENT_TYPE, "text/txt");*/
    
            // Specify custom metadata. 
            Map<String, String> userMetadata = new HashMap<String, String>();
            /*userMetadata.put("key1","value1");
            userMetadata.put("key2","value2");*/
    
            URL signedUrl = null;
            try {
                // Specify the validity period of the signed URL. Unit: milliseconds. In this example, the validity period is set to 1 hour. 
                Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
    
                // Generate the signed URL. 
                GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.PUT);
                // Specify the expiration time. 
                request.setExpiration(expiration);
    
                // Add the headers to the request. 
                request.setHeaders(headers);
                // Add custom metadata. 
                request.setUserMetadata(userMetadata);
    
                // Generate a signed URL that allows HTTP PUT requests. 
                signedUrl = ossClient.generatePresignedUrl(request);
                // Display the signed 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());
            }
        }
    }

    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\Credentials\EnvironmentVariableCredentialsProvider;
    use OSS\OssClient;
    use OSS\Core\OssException;
    use OSS\Http\RequestCore;
    use OSS\Http\ResponseCore;
    
    // 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 https://oss-cn-hangzhou.aliyuncs.com. 
    $endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    // Specify the bucket name. 
    $bucket= "examplebucket";
    // Specify the full path of the object. Do not include the bucket name in the full path of the object. 
    $object = "exampleobject.txt";
    // Set the validity period of the signed URL to 3600. Unit: seconds. 
    $timeout = 3600;
    try {
        $config = array(
            "provider" => $provider,
            "endpoint" => $endpoint,        
        );
        $ossClient = new OssClient($config);
    
        // Generate the signed URL. 
        $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT");
    } catch (OssException $e) {
        printf(__FUNCTION__ . ": FAILED\n");
        printf($e->getMessage() . "\n");
        return;
    }
    print(__FUNCTION__ . ": signedUrl: " . $signedUrl . "\n");

    Node.js

    const OSS = require("ali-oss");
    const { default: axios } = require("axios");
    const fs = require("fs");
    
    const client = new OSS({
      // 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 oss-cn-hangzhou. 
      region: "oss-cn-hangzhou",
      // 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,
      // Specify the name of the bucket. 
      bucket: "examplebucket",
    });
    
    // Generate a signed URL that is used to upload a local file. 
    const url = client.signatureUrl("exampleobject.txt", {
      method: "PUT",
      "Content-Type": "application/x-www-form-urlencoded",
    });
    console.log(url);

    Python

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    import requests
    
    # 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.ProviderAuth(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 https://oss-cn-hangzhou.aliyuncs.com. 
    # Specify the name of the bucket. Example: examplebucket. 
    bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
    # Specify the full path of the object. Do not include the bucket name in the full path. 
    object_name = 'exampleobject.txt'
    
    # Specify headers. 
    headers = dict()
    # Specify Content-Type. 
    headers['Content-Type'] = 'text/txt'
    # Specify the storage class of the object. 
    headers["x-oss-storage-class"] = "Standard"
    
    # Generate a signed URL that is used to upload a local file. Set the validity period of the signed URL to 60 seconds. 
    # By default, OSS identifies the forward slashes (/) in the full path of an object as escape characters when a signed URL is generated. Therefore, the signed URL cannot be used directly. 
    # 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. Then, you can use the generated signed URL to upload the object. 
    url = bucket.sign_url('PUT', object_name, 60, slash_safe=True, headers=headers)
    print ('The signed URL:', url)

    Browser.js

    // Generate temporary access credentials. 
    const OSS = require("ali-oss");
    const STS = require("ali-oss").STS;
    // const cors = require("cors");
    
    const stsClient = new STS({
      // 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,
    });
    // Specify the name of the bucket. Example: examplebucket. 
    const bucket = "examplebucket";
    // 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 oss-cn-hangzhou. 
    const region = "yourRegion";
    // Specify the ARN of the RAM role. 
    const roleArn = "acs:ram::137918634953****:role/ossram";
    const getSts = () => {
      stsClient
        .assumeRole(
          roleArn,
          `{
            "Statement": [
              {
                "Effect": "Allow",
                "Action": "*",
                "Resource": [
                  "acs:oss:*:*:examplebucket/*"
                ]
              }
            ]
          }`,
          3000 // Specify the time when the security token expires. 
        )
        .then((r) => {
          console.log("send:", r.credentials);
          const { SecurityToken, AccessKeyId, AccessKeySecret } = r.credentials;
          const client = new OSS({
            bucket,
            region,
            accessKeyId: AccessKeyId,
            accessKeySecret: AccessKeySecret,
            stsToken: SecurityToken,
            refreshSTSTokenInterval: 9000,
          });
          // Specify the name of the object to be uploaded to the bucket. 
          const url = client.asyncSignatureUrl("example.txt", {
            expires: 3600,
            method: "PUT",
            // Specify Content-Type. 
            "Content-Type": "text/plain;charset=UTF-8",
          });
          console.log("url:", url);
          // client.put("example.txt", Buffer.from("body")).then((res) => {
          //   console.log("res", res.url);
          // });
        });
    };
    getSts();
    

    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";
    // Specify Content-Type. 
    String contentType = "application/octet-stream";
    String url = null;
    try {
        // Generate a signed URL used to upload the object. 
        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectKey);
        // Set the validity period of the signed URL to 30 minutes. 
        request.setExpiration(30*60);
        request.setContentType(contentType);    
        request.setMethod(HttpMethod.PUT);
        url = mOss.presignConstrainedObjectURL(request);
        Log.d("url", url);
    } catch (ClientException e) {
        e.printStackTrace();
    }

    Go

    package main
    
    import (
        "fmt"
        "os"
        "github.com/aliyun/aliyun-oss-go-sdk/oss"
    )
    
    func HandleError(err error) {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    
    func main() {
    	// 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, err := oss.NewEnvironmentVariableCredentialsProvider()
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	// Create an OSSClient instance. 
    	// 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. Specify your actual endpoint. 
    	client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
        // Specify the name of the bucket. Example: examplebucket. 
        bucketName := "examplebucket"
        // Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path. 
        objectName := "exampledir/exampleobject.txt"
        bucket, err := client.Bucket(bucketName)
        if err != nil {
            HandleError(err)
        }
        // Generate a signed URL that is used to upload a local file. Set the validity period of the signed URL to 60 seconds. 
        signedURL, err := bucket.SignURL(objectName, oss.HTTPPut, 60)
        if err != nil {
            HandleError(err)
        }
    
        // To use a signed URL that contains custom parameters to access an object from a browser, make sure that the ContentType value contained in the URL is the same as the ContentType value specified in the request. 
        options := []oss.Option{
            oss.Meta("myprop", "mypropval"),
            oss.ContentType("text/plain"),
        }
        
        signedURL, err = bucket.SignURL(objectName, oss.HTTPPut, 60, options...)
        if err != nil {
            HandleError(err)
        }
        fmt.Printf("Sign Url:%s\n", signedURL)
    }

    iOS

    // Specify the name of the bucket. 
    NSString *bucketName = @"examplebucket";
    // Specify the name of the object. 
    NSString *objectKey = @"exampleobject.txt";
    NSURL *file = [NSURL fileURLWithPath:@"<filePath>"];
    NSString *contentType = [OSSUtil detemineMimeTypeForFilePath:file.absoluteString uploadName:objectKey];
    __block NSString *urlString;
    // Generate a signed URL with a specified validity period for uploading the object. In this example, the validity period of the URL is 30 minutes. 
    OSSTask *task = [client presignConstrainURLWithBucketName:bucketName
                                                withObjectKey:objectKey
                                                   httpMethod:@"PUT"
                                       withExpirationInterval:30 * 60
                                               withParameters:@{}
                                                  contentType:contentType
                                                   contentMd5:nil];
    [task continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
        if (task.error) {
            NSLog(@"presign error: %@", task.error);
        } else {
            urlString = task.result;
            NSLog(@"url: %@", urlString);
        }
        return nil;
    }];
  2. Use the signed URL to upload a local file.

    The following sample code provides examples on how to use a signed URL to upload a local file by using OSS SDKs for common programming languages. For more information about how to use a signed URL to upload a local file by using OSS SDKs for other programming languages, see Overview.

    Java

    import org.apache.http.HttpEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPut;
    import org.apache.http.entity.FileEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import java.io.*;
    import java.util.*;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
        
            // Specify the full path of the local file that you want to upload. By default, if you do not specify the path of the local file, the file is uploaded from the path of the project to which the sample program belongs. 
            String pathName = "D:\\examplefile.txt";
            // Enter the signed URL generated in Step 1. 
            String signedUrl = "yourSignedUrl";        
    
            Map<String, String> headers = new HashMap<String, String>();
            Map<String, String> userMetadata = new HashMap<String, String>();
    
    
            // Use the signed URL to authorize third-party users to upload the local file. In this example, HttpClients is used. 
            putObjectWithHttp(signedUrl, pathName, headers, userMetadata);
        }
    
    
        public static void putObjectWithHttp(String signedUrl, String pathName, Map<String, String> headers, Map<String, String> userMetadata) throws IOException {
            CloseableHttpClient httpClient = null;
            CloseableHttpResponse response = null;
            try {
                HttpPut put = new HttpPut(signedUrl);
                HttpEntity entity = new FileEntity(new File(pathName));
                put.setEntity(entity);
                // If you configure headers such as the user metadata and storage class when a signed URL is generated, these headers must be sent to the server when the signed URL is used to upload the local file. If headers for the signature are inconsistent with those sent to the server, a signature error is reported. 
                for(Map.Entry header: headers.entrySet()){
                    put.addHeader(header.getKey().toString(),header.getValue().toString());
                }
                for(Map.Entry meta: userMetadata.entrySet()){
                    // If userMeta is used, the x-oss-meta- prefix is added to userMeta. If you use other methods to generate a signed URL, the x-oss-meta- prefix is also added to userMeta. 
                    put.addHeader("x-oss-meta-"+meta.getKey().toString(), meta.getValue().toString());
                }
    
                httpClient = HttpClients.createDefault();
    
                response = httpClient.execute(put);
    
                System.out.println("Upload status code:"+response.getStatusLine().getStatusCode());
                if(response.getStatusLine().getStatusCode() == 200){
                    System.out.println("Successfully upload the object by using the network library");
                }
                System.out.println(response.toString());
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                response.close();
                httpClient.close();
            }
        }
    }

    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\Http\RequestCore;
    use OSS\Http\ResponseCore;
    
    // Enter the signed URL generated in Step 1. 
    $signedUrl = 'yourSignedUrl';
    $content = "Hello OSS";
    $request = new RequestCore($signedUrl);
    // Use the signed URL to upload the local file. 
    $request->set_method('PUT');
    $request->add_header('Content-Type', '');
    $request->add_header('Content-Length', strlen($content));
    $request->set_body($content);
    $request->send_request();
    $res = new ResponseCore($request->get_response_header(),
        $request->get_response_body(), $request->get_response_code());
    if ($res->isOK()) {
        print(__FUNCTION__ . ": OK" . "\n");
    } else {
        print(__FUNCTION__ . ": FAILED" . "\n");
    };  

    Node.js

    const OSS = require("ali-oss");
    const { default: axios } = require("axios");
    const fs = require("fs");
    
    // Enter the signed URL generated in Step 1. 
    const url = "yourSignedUrl";
    
    // Specify the full path of the local file. 
    const file = fs.readFileSync("D:\\examplefile.txt");
    
    // Use the signed URL to upload the local file. 
    axios({
      url,
      method: "PUT",
      data: file,
    })
      .then((r) => console.log(r))
      .catch((e) => console.log(e));
    

    Python

    # -*- coding: utf-8 -*-
    import oss2
    import requests
    # Enter the signed URL generated in Step 1. 
    url = 'yourSignedUrl'
    
    # Specify headers. 
    headers = dict()
    # Specify Content-Type. 
    headers['Content-Type'] = 'text/txt'
    # Specify the storage class of the object. 
    headers["x-oss-storage-class"] = "Standard"
    
    # Use the signed URL to upload the local file. 
    # Specify the full path of the local file. Example: D:\\examplefile.txt. 
    requests.put(url, data=open('D:\\examplefile.txt', 'rb').read(), headers=headers)

    Browser.js

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <title>Document</title>
      </head>
      <body>
        <script src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.18.0.min.js"></script>
        <script>
          // Enter the signed URL generated in Step 1. 
          const url = "yourSignatureUrl";
    
          var xhr = new XMLHttpRequest();
          xhr.open("PUT", url, true);
    
          xhr.onload = function () {
            // Add code for further operations. 
          };
    
          // xhr.send(null);
          xhr.send("string");
          // xhr.send(new Blob());
          // xhr.send(new Int8Array());
          // xhr.send({ form: 'data' });
          // xhr.send(document);
        </script>
      </body>
    </html>
    

    Android

    // Enter the generated signed URL. 
    String url = "";
    // Specify the full path of the local file. 
    String localFile = "/storage/emulated/0/oss/examplefile";
    // Specify Content-Type. 
    String contentType = "application/octet-stream";
    // Upload the object by using the signed URL. 
    OkHttpClient client = new OkHttpClient();
    Request putRequest = new Request.Builder()
            .url(url)
            .put(RequestBody.create(MediaType.parse(contentType), new File(localFile)))
            .build();
    client.newCall(putRequest).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }
    
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.d("response", response.body().string());
        }
    });

    Go

    package main
    
    import (
    	"fmt"
    	"os"
    	"strings"
    
    	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    )
    
    func main() {
    	client, err := oss.New("oss-cn-hangzhou.aliyuncs.com", "", "")
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	// Specify the name of the bucket. Example: examplebucket. 
    	bucketName := "examplebucket"
    
    
    	bucket, err := client.Bucket(bucketName)
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
        // Enter the signed URL generated in Step 1. 
    	signedURL := "yourSignedUrl"
    
    	var val = "Go with Alibaba Cloud"
    	err = bucket.PutObjectWithURL(signedURL, strings.NewReader(val))
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    }
    

    iOS

    // Upload the object by using the signed URL. 
    NSURL * url = [NSURL URLWithString:urlString];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"PUT";
    request.allHTTPHeaderFields = @{OSSHttpHeaderContentType: contentType};
    NSURLSession * session = [NSURLSession sharedSession];
    NSURLSessionTask * sessionTask = [session uploadTaskWithRequest:request
                                                           fromFile:file
                                                  completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            NSLog(@"upload error: %@", error);
            return;
        } else if (((NSHTTPURLResponse*)response).statusCode == 203 ||
                   ((NSHTTPURLResponse*)response).statusCode >= 300) {
            NSString *body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"upload error: %@", body);
            return;
        }
        NSLog(@"upload success");
    }];
    [sessionTask resume];