有奖捉虫:办公协同&微信生态&物联网文档专题 HOT

简介

对象存储(Cloud Object Storage,COS)支持使用预签名 URL 进行对象的上传、下载,原理是将签名嵌入 URL 生成签名链接。您可以通过签名的有效期,控制预签名 URL 的生效时间。本文档提供关于生成对象预签名链接的示例代码。
生成预签名 URL 支持使用永久密钥或临时密钥。
使用永久密钥来生成预签名,注意遵循最小权限原则,权限范围仅限于上传或下载操作,并且合理设置签名生效时长。
使用 临时密钥 生成预签名,可以通过临时授权的方式进一步提高预签名上传、下载等请求的安全性。申请临时密钥时,请遵循 最小权限指引原则,防止泄露目标存储桶或对象之外的资源。
获取签名/预签名函数,默认签入 Header Host;您也可以选择不签入 Header Host,但可能导致请求失败或安全漏洞。

使用方法

关于使用预签名 URL 上传的说明请参见 预签名授权上传
使用预签名 URL 下载的说明请参见 预签名授权下载

注意事项

当存储桶为私有读写时,请求对象时需携带签名用于身份验证,也就是 临时密钥
如您使用的存储桶权限为公有读,请求对象时无需携带签名,可直接通过链接访问对象。
临时密钥生成的预签名 URL,其过期时间由临时密钥和预签名 URL 两个的过期时间共同限制,当其中任何一个时间到期,临时密钥生成的预签名 URL 都会到期。

创建 COSClient

执行任何和 COS 服务相关请求之前,都需要生成 COSClient 类的对象,COSClient 实例是并发安全的,这里推荐一个进程只创建一个 COSClient 实例,当不会再通过这个实例发起请求的时候,再选择关闭这个实例。

生成预签名 URL

此部分代码是通用性示例。
方法原型
public URL generatePresignedUrl(String bucketName, String key, Date expiration, HttpMethodName method, Map<String, String> headers, Map<String, String> params, Boolean signPrefixMode, Boolean signHost) throws CosClientException
请求示例
// 调用 COS 接口之前必须保证本进程存在一个 COSClient 实例,如果没有则创建
// 详细代码参见本页:创建 COSClient
COSClient cosClient = createCOSClient();

// 存储桶的命名格式为 BucketName-APPID,此处填写的存储桶名称必须为此格式
String bucketName = "examplebucket-1250000000";
// 对象键(Key)是对象在存储桶中的唯一标识。详情请参见 [对象键](https://cloud.tencent.com/document/product/436/13324)
String key = "exampleobject";

// 设置签名过期时间(可选), 若未进行设置则默认使用 ClientConfig 中的签名过期时间(1小时)
// 这里设置签名在半个小时后过期
Date expirationDate = new Date(System.currentTimeMillis() + 30 * 60 * 1000);

// 填写本次请求的参数,需与实际请求相同,能够防止用户篡改此签名的 HTTP 请求的参数
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "value1");

// 填写本次请求的头部,需与实际请求相同,能够防止用户篡改此签名的 HTTP 请求的头部
Map<String, String> headers = new HashMap<String, String>();
headers.put("header1", "value1");

// 请求的 HTTP 方法,上传请求用 PUT,下载请求用 GET,删除请求用 DELETE
HttpMethodName method = HttpMethodName.GET;

URL url = cosClient.generatePresignedUrl(bucketName, key, expirationDate, method, headers, params);
System.out.println(url.toString());

// 确认本进程不再使用 cosClient 实例之后,关闭即可
cosClient.shutdown();
参数说明
参数名称
描述
类型
是否必填
method
HTTP 方法,可选:GET、POST、PUT、DELETE、HEAD
HttpMethodName
bucketName
存储桶名称,存储桶的命名格式为 BucketName-APPID,详情请参见 命名规范
String
key
对象键(Key)是对象在存储桶中的唯一标识,详情请参见 对象键注意:用户无需对key进行编码操作
String
expiration
签名过期的时间,可以设置任意一个未来的时间,不设置则默认是1小时之后过期
Date
headers
签名头部
Map<String, String>
params
签名参数
Map<String, String>
signPrefixMode
是否以 sign 参数指定签名(不推荐),默认 false
boolean
signHost
是否签入 Host 头部(推荐),默认 true
boolean

生成覆盖返回头部的预签名下载 URL

方法原型
public URL generatePresignedUrl(GeneratePresignedUrlRequest req, boolean signHost) throws CosClientException
请求示例
// 调用 COS 接口之前必须保证本进程存在一个 COSClient 实例,如果没有则创建
// 详细代码参见本页:创建 COSClient
COSClient cosClient = createCOSClient();

// 存储桶的命名格式为 BucketName-APPID,此处填写的存储桶名称必须为此格式
String bucketName = "examplebucket-1250000000";
// 对象键(Key)是对象在存储桶中的唯一标识。详情请参见 [对象键](https://cloud.tencent.com/document/product/436/13324)
String key = "exampleobject";

GeneratePresignedUrlRequest req =
new GeneratePresignedUrlRequest(bucketName, key, HttpMethodName.GET);

// 设置下载时返回的 http 头
ResponseHeaderOverrides responseHeaders = new ResponseHeaderOverrides();
String responseContentType = "image/x-icon";
String responseContentLanguage = "zh-CN";
// 设置返回头部里包含文件名信息
String responseContentDispositon = "filename=exampleobject";
String responseCacheControl = "no-cache";
String cacheExpireStr =
DateUtils.formatRFC822Date(new Date(System.currentTimeMillis() + 24L * 3600L * 1000L));
responseHeaders.setContentType(responseContentType);
responseHeaders.setContentLanguage(responseContentLanguage);
responseHeaders.setContentDisposition(responseContentDispositon);
responseHeaders.setCacheControl(responseCacheControl);
responseHeaders.setExpires(cacheExpireStr);

req.setResponseHeaders(responseHeaders);

// 设置签名过期时间(可选),若未进行设置,则默认使用 ClientConfig 中的签名过期时间(1小时)
// 这里设置签名在半个小时后过期
Date expirationDate = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);
req.setExpiration(expirationDate);

// 填写本次请求的参数
req.addRequestParameter("param1", "value1");
// 填写本次请求的头部
// host 必填
req.putCustomRequestHeader(Headers.HOST, cosClient.getClientConfig().getEndpointBuilder().buildGeneralApiEndpoint(bucketName));
req.putCustomRequestHeader("header1", "value1");

URL url = cosClient.generatePresignedUrl(req);
System.out.println(url.toString());

// 确认本进程不再使用 cosClient 实例之后,关闭即可
cosClient.shutdown();
参数说明
参数名称
描述
类型
是否必填
req
预签名请求类
GeneratePresignedUrlRequest
signHost
是否签入 Host 头部(推荐)默认 true
boolean
Request 成员说明:
Request 成员
设置方法
描述
类型
method
构造函数或 set 方法
HTTP 方法,可选:GET、POST、PUT、DELETE、HEAD
HttpMethodName
bucketName
构造函数或 set 方法
存储桶名称,存储桶的命名格式为 BucketName-APPID,详情请参见 命名规范
String
key
构造函数或 set 方法
对象键(Key)是对象在存储桶中的唯一标识,详情请参见 对象键注意:用户无需对key进行编码操作
String
expiration
set 方法
签名过期的时间,可以设置任意一个未来的时间,不设置则默认是1小时之后过期
Date
contentType
set 方法
要签名的请求中的 Content-Type
String
contentMd5
set 方法
要签名的请求中的 Content-Md5
String
responseHeaders
set 方法
签名的下载请求中要覆盖的返回的 HTTP 头
ResponseHeaderOverrides
versionId
set 方法
在存储桶开启版本控制的时候,指定对象的版本号
String

生成限速的预签名下载 URL

关于限速的使用说明,可参见 单链接限速

请求示例

以生成限速的预签名下载 URL 为例:
public static void GenerateSimplePresignedDownloadUrl() {
// 1 初始化用户身份信息(secretId, secretKey)
// SECRETID 和 SECRETKEY 请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理
String secretId = System.getenv("secretId");//用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
String secretKey = System.getenv("secretKey");//用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置 bucket的区域
// COS_REGION 参数:配置成存储桶 bucket 的实际地域,例如 ap-beijing,更多 COS 地域的简称请参见 https://cloud.tencent.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region("COS_REGION"));
// 3 生成 cos 客户端
COSClient cosclient = new COSClient(cred, clientConfig);
// bucket 名需包含 appid
String bucketName = "examplebucket-1250000000";

String key = "exampleobject";
GeneratePresignedUrlRequest req =
new GeneratePresignedUrlRequest(bucketName, key, HttpMethodName.GET);
// 设置签名过期时间(可选), 若未进行设置则默认使用 ClientConfig 中的签名过期时间(1小时)
// 这里设置签名在半个小时后过期
Date expirationDate = new Date(System.currentTimeMillis() + 30 * 60 * 1000);
req.setExpiration(expirationDate);

// 填写本次请求的参数
// 设定限速值,例如128KB/s
req.addRequestParameter("x-cos-traffic-limit", "1048576");

// 填写本次请求的头部。Host 必填
req.putCustomRequestHeader(Headers.HOST,
cosclient.getClientConfig().getEndpointBuilder().buildGeneralApiEndpoint(bucketName));
//req.putCustomRequestHeader("header1", "value1");

URL url = cosclient.generatePresignedUrl(req);
System.out.println(url.toString());

cosclient.shutdown();
}

生成预签名上传 URL

请求示例

public static void GeneratePresignedUploadUrl() {
// 1 初始化用户身份信息(secretId, secretKey)
// SECRETID 和 SECRETKEY 请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理
String secretId = System.getenv("secretId");//用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
String secretKey = System.getenv("secretKey");//用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置 bucket的区域
// COS_REGION 参数:配置成存储桶 bucket 的实际地域,例如 ap-beijing,更多 COS 地域的简称请参见 https://cloud.tencent.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region("COS_REGION"));
// 3 生成 cos 客户端
COSClient cosclient = new COSClient(cred, clientConfig);
// bucket 名需包含 appid
String bucketName = "examplebucket-1250000000";

String key = "exampleobject";
Date expirationTime = new Date(System.currentTimeMillis() + 30 * 60 * 1000); // 填写本次请求的 header。Host 头部会自动补全,只需填入其他头部 Map<String, String> headers = new HashMap<String,String>(); // 填写本次请求的 params。 Map<String, String> params = new HashMap<String,String>(); URL url = cosclient.generatePresignedUrl(bucketName, key, expirationTime, HttpMethodName.PUT, headers, params); try { HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestMethod("PUT"); OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream()); // 写入要上传的数据 out.write("This text uploaded as object."); out.close(); int responseCode = connection.getResponseCode(); System.out.println("Service returned response code " + responseCode); } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }

cosclient.shutdown();
}

生成签名后拼接预签名 URL

构造 COS 请求的签名。生成后需拼接完整的 URL。推荐使用临时密钥来生成签名。



常见问题

使用自定义域名时,如何生成预签名 URL?

您可以通过在使用 SDK 初始化时,指定对应的自定义源站域名,从而实现在生成预签名URL时进行指定自定义域名功能需求,例如 JavaSDK
初始化完成之后,然后实现 生成预签名URL