简介
对象存储(Cloud Object Storage,COS)支持使用预签名 URL 进行对象的上传、下载,原理是将签名嵌入 URL 生成签名链接。您可以通过签名的有效期,控制预签名 URL 的生效时间。本文档提供 Python SDK 获取签名、预签名 URL 、下载预签名 URL 的接口,用于将请求分发使用。
生成预签名 URL 支持使用永久密钥或临时密钥。
使用永久密钥来生成预签名,注意遵循最小权限原则,权限范围仅限于上传或下载操作,并且合理设置签名生效时长。
获取签名/预签名函数,默认签入 Header Host;您也可以选择不签入 Header Host,但可能导致请求失败或安全漏洞。
注意事项
2024年1月1日后创建的桶 不支持使用默认域名在浏览器预览文件,建议您配置自定义域名,详情请参见 存储桶切换自定义域名。
当存储桶为私有读写时,请求对象时需携带签名用于身份验证,也就是 临时密钥。
如您使用的存储桶权限为公有读,请求对象时无需携带签名,可直接通过链接访问对象。
临时密钥生成的预签名 URL,其过期时间由临时密钥和预签名 URL 两个的过期时间共同限制,当其中任何一个时间到期,临时密钥生成的预签名 URL 都会到期。
在获取签名时强烈建议将敏感请求头部和请求参数算入签名,这样可以避免相关请求头部和请求参数被使用者篡改,杜绝权限越界的情况发生。同时 SDK 会默认将请求域名算入签名,如果分发后修改了请求域名会导致访问失败,此时可以在获取签名时传入参数忽略请求域名,详细方法参见下面的请求示例。
相关示例
功能名称 | 描述 | 示例代码 |
生成预签名 URL | 提供了生成并使用预签名 URL 的功能。 |
使用案例:生成预签名 URL
功能说明
获取预签名链接用于分发。
方法原型
get_presigned_url(Bucket, Key, Method, Expired=300, Params={}, Headers={})
全部参数请求示例
response = client.get_presigned_url(Bucket='examplebucket-1250000000',Key='exampleobject',Method='PUT'|'POST'|'GET'|'DELETE'|'HEAD',Expired=300,Headers={'header1': 'string','header2': 'string'},Params={'param1': 'string','param2': 'string'},SignHost=True|False)
参数说明
参数名称 | 参数描述 | 类型 | 是否必填 |
Bucket | 存储桶名称,由 BucketName-APPID 构成 | String | 是 |
Key | 对象键(Key)是对象在存储桶中的唯一标识。例如,在对象的访问域名 examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/doc/pic.jpg 中,对象键为 doc/pic.jpg (用户无需进行 URL 编码) | String | 是 |
Method | 对应操作的 Method, 可选值为 'PUT','POST','GET','DELETE','HEAD' | String | 是 |
Expired | 签名过期时间,单位为秒 | Int | 否 |
Headers | 预签名 URL 中要签入的请求头部。预签名 URL 本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值。可以签入的 Headers 和具体的操作相关,例如上传对象可以签入的 Headers 参见 PUT Object 中的请求头 描述 | Dict | 否 |
Params | 预签名 URL 中的请求参数。指定了请求参数,则 URL 中会携带此请求参数,并且请求参数会算入签名,不允许使用者修改请求参数的值。可以携带的 Params 和具体的操作相关,例如下载对象可以携带和签入的 Params 参见 GET Object 中的请求参数 描述 | Dict | 否 |
SignHost | 请求域名是否算入签名,默认值 True,签名后使用者需要修改请求域名时设置为 False | Bool | 否 |
返回结果说明
该方法返回值为预签名的 URL。
请求示例一:生成上传预签名 URL
# -*- coding=utf-8from qcloud_cos import CosConfigfrom qcloud_cos import CosS3Clientimport sysimport osimport loggingimport requests# 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息logging.basicConfig(level=logging.INFO, stream=sys.stdout)# 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket# COS 支持的所有 region 列表参见https://cloud.tencent.com/document/product/436/6224token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)client = CosS3Client(config)# 生成上传 URL,未限制请求头部和请求参数url = client.get_presigned_url(Method='PUT',Bucket='examplebucket-1250000000',Key='exampleobject',Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 生成上传 URL,同时限制存储类型和上传速度url = client.get_presigned_url(Method='PUT',Bucket='examplebucket-1250000000',Key='exampleobject',Headers={'x-cos-storage-class':'STANDARD_IA','x-cos-traffic-limit':'819200' # 预签名 URL 本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值},Expired=300 # 300秒后过期,过期时间请根据自身场景定义)print(url)# 生成上传 URL,只能上传指定的文件内容url = client.get_presigned_url(Method='PUT',Bucket='examplebucket-1250000000',Key='exampleobject',Headers={'Content-MD5':'string'}, # 约定使用此 URL 上传对象的人必须携带 MD5 请求头部,并且请求头部的值必须是这里指定的值,这样就限定了文件的内容Expired=300 # 300秒后过期,过期时间请根据自身场景定义)print(url)# 生成上传 URL,只能用于上传 ACLurl = client.get_presigned_url(Method='PUT',Bucket='examplebucket-1250000000',Key='exampleobject',Params={'acl':''}, # 指定了请求参数,则 URL 中会携带此请求参数,并且请求参数会算入签名,不允许使用者修改请求参数的值Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 生成上传 URL,请求域名不算入签名,签名后使用者需要修改请求域名时使用url = client.get_presigned_url(Method='PUT',Bucket='examplebucket-1250000000',Key='exampleobject',SignHost=False, # 请求域名不算入签名,允许使用者修改请求域名,有一定安全风险Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 使用上传 URLretry = 1 # 简单重试1次for i in range(retry + 1):response = requests.put(url=url, data=b'123')if response.status_code == 400 or response.status_code >= 500: # 只对400和5xx错误码进行重试time.sleep(1) # 延迟 1s 后再重试continue# 请求结束, 打印结果并退出循环print(response)break
请求示例二:生成下载预签名 URL
# -*- coding=utf-8from qcloud_cos import CosConfigfrom qcloud_cos import CosS3Clientimport sysimport osimport loggingimport requests# 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息logging.basicConfig(level=logging.INFO, stream=sys.stdout)# 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket# COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)client = CosS3Client(config)# 生成下载 URL,未限制请求头部和请求参数url = client.get_presigned_url(Method='GET',Bucket='examplebucket-1250000000',Key='exampleobject',Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 生成下载 URL,同时指定响应的 content-disposition 头部,让文件在浏览器另存为,而不是显示url = client.get_presigned_url(Method='GET',Bucket='examplebucket-1250000000',Key='exampleobject',Params={'response-content-disposition':'attachment; filename=example.xlsx' # 下载时保存为指定的文件# 除了 response-content-disposition,还支持 response-cache-control、response-content-encoding、response-content-language、# response-content-type、response-expires 等请求参数,详见下载对象 API,https://cloud.tencent.com/document/product/436/7753},Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 生成下载 URL,同时限制下载速度url = client.get_presigned_url(Method='GET',Bucket='examplebucket-1250000000',Key='exampleobject',Headers={'x-cos-traffic-limit':'819200'}, # 预签名URL本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值Expired=300 # 300秒后过期,过期时间请根据自身场景定义)print(url)# 生成下载 URL,只能用于下载 ACLurl = client.get_presigned_url(Method='GET',Bucket='examplebucket-1250000000',Key='exampleobject',Params={'acl':''}, # 指定了请求参数,则 URL 中会携带此请求参数,并且请求参数会算入签名,不允许使用者修改请求参数的值Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 生成下载 URL,请求域名不算入签名,签名后使用者需要修改请求域名时使用url = client.get_presigned_url(Method='GET',Bucket='examplebucket-1250000000',Key='exampleobject',SignHost=False, # 请求域名不算入签名,允许使用者修改请求域名,有一定安全风险Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 使用下载URLretry = 1 # 简单重试1次for i in range(retry + 1):response = requests.get(url)if response.status_code == 400 or response.status_code >= 500: # 只对400和5xx错误码进行重试time.sleep(1) # 延迟 1s 后再重试continue# 请求结束, 打印结果并退出循环print(response)break
请求示例三:使用临时密钥生成下载预签名 URL
# -*- coding=utf-8from qcloud_cos import CosConfigfrom qcloud_cos import CosS3Clientimport sysimport osimport loggingimport requests# 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息logging.basicConfig(level=logging.INFO, stream=sys.stdout)# 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket# COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)client = CosS3Client(config)# 生成下载 URLurl = client.get_presigned_url(Method='GET',Bucket='examplebucket-1250000000',Key='exampleobject',Headers={'x-cos-traffic-limit':'819200'}, # 预签名 URL 本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值Params={'x-cos-security-token': 'string' # 使用临时密钥需要填入 Token 到请求参数},Expired=120, # 120秒后过期,过期时间请根据自身场景定义SignHost=False # 请求域名不算入签名,签名后使用者需要修改请求域名时使用,有一定安全风险)print(url)# 使用下载 URLretry = 1 # 简单重试1次for i in range(retry + 1):response = requests.get(url)if response.status_code == 400 or response.status_code >= 500: # 只对400和5xx错误码进行重试time.sleep(1) # 延迟 1s 后再重试continue# 请求结束, 打印结果并退出循环print(response)break
使用案例:生成下载对象的预签名 URL
功能说明
获取预签名下载链接用于直接下载。
方法原型
get_presigned_download_url(Bucket, Key, Expired=300, Params={}, Headers={})
全部参数请求示例
response = client.get_presigned_download_url(Bucket='examplebucket-1250000000',Key='exampleobject',Expired=300,Headers={'header1': 'string'},Params={'param1': 'string','param2': 'string'},SignHost=True|False)
参数说明
参数名称 | 参数描述 | 类型 | 是否必填 |
Bucket | 存储桶名称,由 BucketName-APPID 构成 | String | 是 |
Key | 对象键(Key)是对象在存储桶中的唯一标识。例如,在对象的访问域名 examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/doc/pic.jpg 中,对象键为 doc/pic.jpg (用户无需进行 URL 编码) | String | 是 |
Expired | 签名过期时间,单位为秒 | Int | 否 |
Headers | 预签名 URL 中要签入的请求头部。预签名 URL 本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值。可以签入的 Headers 和具体的操作相关,例如上传对象可以签入的 Headers 参见 PUT Object 中的请求头 描述 | Dict | 否 |
Params | 预签名 URL 中的请求参数。指定了请求参数,则 URL 中会携带此请求参数,并且请求参数会算入签名,不允许使用者修改请求参数的值。可以携带的 Params 和具体的操作相关,例如下载对象可以携带和签入的 Params 参见 GET Object 中的请求参数描述 | Dict | 否 |
SignHost | 请求域名是否算入签名,默认值 True,签名后使用者需要修改请求域名时设置为 False | Bool | 否 |
请求示例
# -*- coding=utf-8from qcloud_cos import CosConfigfrom qcloud_cos import CosS3Clientimport sysimport osimport loggingimport requests# 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息logging.basicConfig(level=logging.INFO, stream=sys.stdout)# 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket# COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)client = CosS3Client(config)# 生成下载 URL,未限制请求头部和请求参数url = client.get_presigned_download_url(Bucket='examplebucket-1250000000',Key='exampleobject',Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 生成下载 URL,同时指定响应的 content-disposition 头部,让文件在浏览器另存为,而不是显示url = client.get_presigned_download_url(Bucket='examplebucket-1250000000',Key='exampleobject',Params={'response-content-disposition':'attachment; filename=example.xlsx' # 下载时保存为指定的文件# 除了 response-content-disposition,还支持 response-cache-control、response-content-encoding、response-content-language、# response-content-type、response-expires 等请求参数,详见下载对象 API,https://cloud.tencent.com/document/product/436/7753},Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 生成下载 URL,同时限制下载速度url = client.get_presigned_download_url(Bucket='examplebucket-1250000000',Key='exampleobject',Headers={'x-cos-traffic-limit':'819200'}, # 预签名 URL 本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值Expired=300 # 300秒后过期,过期时间请根据自身场景定义)print(url)# 生成下载 URL,只能用于下载 ACLurl = client.get_presigned_download_url(Bucket='examplebucket-1250000000',Key='exampleobject',Params={'acl':''}, # 指定了请求参数,则 URL 中会携带此请求参数,并且请求参数会算入签名,不允许使用者修改请求参数的值Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 生成下载 URL,请求域名不算入签名,签名后使用者需要修改请求域名时使用url = client.get_presigned_download_url(Bucket='examplebucket-1250000000',Key='exampleobject',SignHost=False, # 请求域名不算入签名,允许使用者修改请求域名,有一定安全风险Expired=120 # 120秒后过期,过期时间请根据自身场景定义)print(url)# 生成下载 URL,使用临时密钥签名url = client.get_presigned_download_url(Bucket='examplebucket-1250000000',Key='exampleobject',Params={'x-cos-security-token': 'string' # 使用永久密钥不需要填入 token,如果使用临时密钥需要填入})print(url)# 使用下载 URLretry = 1 # 简单重试1次for i in range(retry + 1):response = requests.get(url)if response.status_code == 400 or response.status_code >= 500: # 只对400和5xx错误码进行重试time.sleep(1) # 延迟 1s 后再重试continue# 请求结束, 打印结果并退出循环print(response)break
返回结果说明
该方法返回值为预签名的下载 URL。