简介
对象存储(Cloud Object Storage,COS)支持使用预签名 URL 进行对象的上传、下载,原理是将签名嵌入 URL 生成签名链接。您可以通过签名的有效期,控制预签名 URL 的生效时间。本文档提供关于生成对象预签名链接的示例代码。
生成预签名 URL 支持使用永久密钥或临时密钥。
使用永久密钥来生成预签名,注意遵循最小权限原则,权限范围仅限于上传或下载操作,并且合理设置签名生效时长。
获取签名/预签名函数,默认签入 Header Host;您也可以选择不签入 Header Host,但可能导致请求失败或安全漏洞。
使用方法
关于使用预签名 URL 上传的说明请参见 预签名授权上传 。
使用预签名 URL 下载的说明请参见 预签名授权下载。
注意事项
当存储桶为私有读写时,请求对象时需携带签名用于身份验证,也就是 临时密钥。
如您使用的存储桶权限为公有读,请求对象时无需携带签名,可直接通过链接访问对象。
临时密钥生成的预签名 URL,其过期时间由临时密钥和预签名 URL 两个的过期时间共同限制,当其中任何一个时间到期,临时密钥生成的预签名 URL 都会到期。
通过 COSClient 生成预签名 URL
创建 COSClient
执行任何和 COS 服务相关请求之前,都需要生成 COSClient 类的对象,COSClient 实例是并发安全的,这里推荐一个进程只创建一个 COSClient 实例,当不会再通过这个实例发起请求的时候,再选择关闭这个实例。
方案一:使用临时密钥创建 COSClient(推荐)
// 创建 COSClient 实例,这个实例用来后续调用请求COSClient createCOSClient() {// 这里需要已经获取到临时密钥的结果。// 临时密钥的生成参见 https://cloud.tencent.com/document/product/436/14048#cos-sts-sdkString tmpSecretId = "TMPSECRETID";String tmpSecretKey = "TMPSECRETKEY";String sessionToken = "SESSIONTOKEN";COSCredentials cred = new BasicSessionCredentials(tmpSecretId, tmpSecretKey, sessionToken);// ClientConfig 中包含了后续请求 COS 的客户端设置:ClientConfig clientConfig = new ClientConfig();// 设置 bucket 的地域// COS_REGION 请参见 https://cloud.tencent.com/document/product/436/6224clientConfig.setRegion(new Region("COS_REGION"));// 设置请求协议, http 或者 https// 5.6.53 及更低的版本,建议设置使用 https 协议// 5.6.54 及更高版本,默认使用了 httpsclientConfig.setHttpProtocol(HttpProtocol.https);// 以下的设置,是可选的:// 设置 socket 读取超时,默认 30sclientConfig.setSocketTimeout(30*1000);// 设置建立连接超时,默认 30sclientConfig.setConnectionTimeout(30*1000);// 如果需要的话,设置 http 代理,ip 以及 portclientConfig.setHttpProxyIp("httpProxyIp");clientConfig.setHttpProxyPort(80);// 生成 cos 客户端。return new COSClient(cred, clientConfig);}
方案二:使用永久密钥创建 COSClient
// 创建 COSClient 实例,这个实例用来后续调用请求COSClient createCOSClient() {// 设置用户身份信息。// SECRETID 和 SECRETKEY 请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理String secretId = System.getenv("secretId");//用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140String secretKey = System.getenv("secretKey");//用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);// ClientConfig 中包含了后续请求 COS 的客户端设置:ClientConfig clientConfig = new ClientConfig();// 设置 bucket 的地域// COS_REGION 请参见 https://cloud.tencent.com/document/product/436/6224clientConfig.setRegion(new Region("COS_REGION"));// 设置请求协议, http 或者 https// 5.6.53 及更低的版本,建议设置使用 https 协议// 5.6.54 及更高版本,默认使用了 httpsclientConfig.setHttpProtocol(HttpProtocol.https);// 以下的设置,是可选的:// 设置 socket 读取超时,默认 30sclientConfig.setSocketTimeout(30*1000);// 设置建立连接超时,默认 30sclientConfig.setConnectionTimeout(30*1000);// 如果需要的话,设置 http 代理,ip 以及 portclientConfig.setHttpProxyIp("httpProxyIp");clientConfig.setHttpProxyPort(80);// 生成 cos 客户端。return new COSClient(cred, clientConfig);}
生成预签名 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 实例,如果没有则创建// 详细代码参见本页:创建 COSClientCOSClient 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,删除请求用 DELETEHttpMethodName 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 | String | 是 | |
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 实例,如果没有则创建// 详细代码参见本页:创建 COSClientCOSClient 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 方法 | String | |
key | 构造函数或 set 方法 | 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/37140String secretKey = System.getenv("secretKey");//用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);// 2 设置 bucket的区域// COS_REGION 参数:配置成存储桶 bucket 的实际地域,例如 ap-beijing,更多 COS 地域的简称请参见 https://cloud.tencent.com/document/product/436/6224ClientConfig clientConfig = new ClientConfig(new Region("COS_REGION"));// 3 生成 cos 客户端COSClient cosclient = new COSClient(cred, clientConfig);// bucket 名需包含 appidString 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/sreq.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/37140String secretKey = System.getenv("secretKey");//用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);// 2 设置 bucket的区域// COS_REGION 参数:配置成存储桶 bucket 的实际地域,例如 ap-beijing,更多 COS 地域的简称请参见 https://cloud.tencent.com/document/product/436/6224ClientConfig clientConfig = new ClientConfig(new Region("COS_REGION"));// 3 生成 cos 客户端COSClient cosclient = new COSClient(cred, clientConfig);// bucket 名需包含 appidString 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。推荐使用临时密钥来生成签名。
方案一:使用临时密钥(推荐)
// 这里需要已经获取到临时密钥的结果。// 临时密钥的生成参见 https://cloud.tencent.com/document/product/436/14048#cos-sts-sdkString tmpSecretId = "TMPSECRETID";String tmpSecretKey = "TMPSECRETKEY";String sessionToken = "SESSIONTOKEN";COSCredentials cred = new BasicSessionCredentials(tmpSecretId, tmpSecretKey, sessionToken);// 存储桶的命名格式为 BucketName-APPID,此处填写的存储桶名称必须为此格式String bucketName = "examplebucket-1250000000";// 对象键(Key)是对象在存储桶中的唯一标识。详情请参见 [对象键](https://cloud.tencent.com/document/product/436/13324)String key = "exampleobject";//若key不是以“/”开头,则需要在 key 的开头加上“/”,否则直接 resource_path=keyString resource_path="/" + key;ClientConfig clientConfig = new ClientConfig(new Region("ap-beijing-1"));// 用来生成签名COSSigner signer = new COSSigner();// 设置签名过期时间(可选),若未进行设置,则默认使用 ClientConfig 中的签名过期时间(1小时)// 这里设置签名在半个小时后过期Date expirationDate = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);// 填写本次请求的参数Map<String, String> params = new HashMap<String, String>();params.put("param1", "value1");// 填写本次请求的头部Map<String, String> headers = new HashMap<String, String>();// host 必填headers.put(Headers.HOST, clientConfig.getEndpointBuilder().buildGeneralApiEndpoint(bucketName));headers.put("header1", "value1");// 请求的 HTTP 方法,上传请求用 PUT,下载请求用 GET,删除请求用 DELETEHttpMethodName method = HttpMethodName.GET;String sign = signer.buildAuthorizationStr(method, resource_path, headers, params, cred, expirationDate, true);
方案二:使用永久密钥
// 设置用户身份信息。// SECRETID 和 SECRETKEY 请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理String secretId = System.getenv("secretId");//用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140String secretKey = System.getenv("secretKey");//用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);// 存储桶的命名格式为 BucketName-APPID,此处填写的存储桶名称必须为此格式String bucketName = "examplebucket-1250000000";// 对象键(Key)是对象在存储桶中的唯一标识。详情请参见 [对象键](https://cloud.tencent.com/document/product/436/13324)String key = "exampleobject";//若 key不是以“/”开头,则需要在 key 的开头加上“/”,否则直接 resource_path=keyString resource_path="/" + key;ClientConfig clientConfig = new ClientConfig(new Region("ap-beijing-1"));// 用来生成签名COSSigner signer = new COSSigner();// 设置签名过期时间(可选),若未进行设置,则默认使用 ClientConfig 中的签名过期时间(1小时)// 这里设置签名在半个小时后过期Date expirationDate = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);// 填写本次请求的参数Map<String, String> params = new HashMap<String, String>();params.put("param1", "value1");// 填写本次请求的头部Map<String, String> headers = new HashMap<String, String>();// host 必填headers.put(Headers.HOST, clientConfig.getEndpointBuilder().buildGeneralApiEndpoint(bucketName));headers.put("header1", "value1");// 请求的 HTTP 方法,上传请求用 PUT,下载请求用 GET,删除请求用 DELETEHttpMethodName method = HttpMethodName.GET;String sign = signer.buildAuthorizationStr(method, resource_path, headers, params, cred, expirationDate, true);
相关示例
常见问题
使用自定义域名时,如何生成预签名 URL?
您可以通过在使用 SDK 初始化时,指定对应的自定义源站域名,从而实现在生成预签名URL时进行指定自定义域名功能需求,例如 JavaSDK。
初始化完成之后,然后实现 生成预签名URL。