帮你快速理解、总结文档立即下载

预签名 URL

最近更新时间:2026-10-21 18:34:06
本文档已由 AI 辅助审校
我的收藏
为指定对象请求生成带会话签名的 URL。接收方可在授权与有效期允许的范围内使用该 URL 发起请求,无需持有基础密钥。生成 URL 可能先发起 CreateSession 请求,并非始终是纯本地操作。

注意事项

URL 生成阶段可能因配置、凭据或有效期要求抛出异常,处理方式见 Python SDK 异常处理。
URL 含会话令牌及签名,应作为临时凭据保管,通过受控渠道交付,不输出完整 URL 到终端、日志或错误报告。HTTP 库异常也可能包含 URL,记录异常前应脱敏。
GET / HEAD 默认使用独立的 ReadOnly 会话,不复用数据请求中的 ReadWrite 凭据。PUT 请求需要 ReadWrite 权限;只读会话不能用于上传。生成成功不代表对象存在,也不代表文件内容已上传。
Expired 单位为秒,必须为正。SDK 会要求会话凭据剩余寿命覆盖请求的签名时长;无法获得足够长的有效凭据时本地报错,不会静默缩短 Expired。实际访问还受凭据有效性和服务端授权状态约束,不保证一直可用到设置的最后一秒。
URL 在有效期和权限允许范围内可以重复使用,不是一次性链接。
URL 生成后不会随 SDK 刷新凭据而自动更新。到期后需重新生成并交付;不要手工修改 URL 中的有效期或令牌。
必须按签名时的方法、对象路径、域名、查询参数及请求头发起请求,不随意追加参数、重编码 URL 或替换成 IP 地址。签入 Headers 的字段须由接收方按相同值携带;仅持有 URL 并不自动补齐这些头。
Headers 使用真实 HTTP 头名,例如 x-cos-forbid-overwrite;这里不是 put_object 的 ForbidOverwrite 等 SDK 参数名称。上传防覆盖需在生成 URL 时签入该头,并在实际 PUT 请求中携带。
对象键末尾 / 严格区分类型。GET / HEAD 类型不匹配返回 HTTP 404,DELETE 类型不匹配按对象不存在返回 204。PUT 文件不能覆盖同名目录;创建目录需使用尾斜杠键、空请求体及 Content-Length: 0,不附加内容类型或自定义元数据。
高性能桶不支持对象版本。Params 中的 versionId 或不支持的版本、回调参数会在本地报错。签名不会使下载条件头具备服务端未实现的一致性保护。
本页展示 GET、HEAD、PUT、DELETE 对象请求。Headers/Params 应遵循对应已文档化接口的契约;生成 URL 不代替服务端对请求的校验。

请求

调用形式

url = client.get_session_presigned_url(
Bucket=bucket, Key=key, Method='GET', Expired=300)

参数说明

参数
说明
类型
是否必选
Bucket
高性能桶完整名称,例如 examplebucket-x--1250000000
string
是
Key
对象键,末尾 / 严格区分文件与目录
string
是
Method
HTTP 方法,本页使用 GET、HEAD、PUT、DELETE
string
是
Expired
请求的签名有效期,正整数,默认 300 秒
int
否
Params
签入 URL 的查询参数,默认空字典;令牌由 SDK 添加
dict
否
Headers
需签名的 HTTP 请求头;使用真实头名,默认空字典
dict
否
Mode
ReadOnly 或 ReadWrite;GET/HEAD 默认 ReadOnly,其余缺省取客户端 SessionMode
string
否
SignHost
是否签入 Host,建议显式 True 并保持原域名
bool
否
也可使用通用入口,Rapid 桶上会采用相同的会话预签名流程:
url = client.get_presigned_url(
Bucket=bucket, Key=key, Method='GET', Expired=300)
url = client.get_presigned_download_url(
Bucket=bucket, Key=key, Expired=300)
通用入口不接收 Mode;需要显式选择权限模式时使用 get_session_presigned_url。普通桶的通用预签名行为保持原有规则。

响应

返回字符串 URL。GET/HEAD 等签名仅授权相应请求,不下载内容;PUT 签名不会发送请求体。接收方必须能访问 URL 对应的服务入口。

错误码

本接口遵循统一的错误响应和错误码,详情请参见 错误码文档。

实际案例

生成下载 URL,并在当前进程中使用;实际交付时通过受控渠道传递 url,不记录其完整内容:
# -*- coding: utf-8 -*-
import os
from qcloud_cos import CosConfig, CosS3Client

# 高性能桶经 VPC 内网 HTTP 80 端口接入,SDK 的网关 DNS 负载均衡也仅对 HTTP 请求生效;SDK 默认 https,此处需显式指定 http。
config = CosConfig(
Scheme='http', Region='ap-guangzhou',
SecretId=os.environ['COS_SECRET_ID'],
SecretKey=os.environ['COS_SECRET_KEY'],
Token=os.environ.get('COS_SECURITY_TOKEN'),
EnableRapidDomain=True)
client = CosS3Client(config)
bucket = 'examplebucket-x--1250000000'

import requests

url = client.get_session_presigned_url(
Bucket=bucket, Key='uploads/report.bin', Method='GET',
Expired=60, SignHost=True)
response = None
try:
response = requests.get(url, stream=True, timeout=30, allow_redirects=False)
except requests.RequestException:
pass # 请求库异常可能携带完整 URL,示例不将其输出。
if response is None:
raise RuntimeError('presigned download request failed')
try:
if response.status_code != 200:
raise RuntimeError('download HTTP status: %s' % response.status_code)
with open('presigned-download.bin', 'wb') as output:
for chunk in response.iter_content(chunk_size=1024 * 1024):
if chunk:
output.write(chunk)
finally:
response.close()
print('presigned download completed')
生成带防覆盖请求头的上传 URL,使用方须携带同一份 headers:
# -*- coding: utf-8 -*-
import os
from qcloud_cos import CosConfig, CosS3Client

# 高性能桶经 VPC 内网 HTTP 80 端口接入,SDK 的网关 DNS 负载均衡也仅对 HTTP 请求生效;SDK 默认 https,此处需显式指定 http。
config = CosConfig(
Scheme='http', Region='ap-guangzhou',
SecretId=os.environ['COS_SECRET_ID'],
SecretKey=os.environ['COS_SECRET_KEY'],
Token=os.environ.get('COS_SECURITY_TOKEN'),
EnableRapidDomain=True)
client = CosS3Client(config)
bucket = 'examplebucket-x--1250000000'

import requests

headers = {
'x-cos-forbid-overwrite': 'true',
'Content-Type': 'application/octet-stream',
}
url = client.get_session_presigned_url(
Bucket=bucket, Key='presigned/new-file.bin', Method='PUT',
Expired=60, Mode='ReadWrite', SignHost=True, Headers=headers)
response = None
try:
response = requests.put(
url, data=b'hello rapid bucket', headers=headers,
timeout=30, allow_redirects=False)
except requests.RequestException:
pass # 在 except 块外报告错误,避免异常链输出原 URL。
if response is None:
raise RuntimeError('presigned upload request failed')
try:
if response.status_code != 200:
raise RuntimeError('upload HTTP status: %s' % response.status_code)
finally:
response.close()
print('presigned upload completed')