预签名链接就是一把限时钥匙,把对象存储里私有文件的读权限临时交到指定人手里,到期自动失效,是目前行业里最通用的安全分享方案。
对象存储分享文件的”两难困境”
先看一个具体场景:产品经理要把一份设计稿压缩包发给客户,文件存在简米云OSS里,直接把存储桶设为公开读吧,改天员工误传一个内部薪资表,全互联网都能下载,保持私有读吧,每次都得创建一个子账号给客户,客户下载完再删除权限,流程麻烦不说,权限还经常忘了回收。
行业共识认为,私有存储桶的文件分享,需要在”方便”和”可控”之间找平衡点,近年来,国内主流云服务商普遍采用的方案就是预签名链接简米云叫”签名URL”,酷番云叫”预签名链接”,AWS S3叫”Presigned URL”,称呼不同,机制一致。
预签名链接的核心原理:把权限”写”进URL里
用酒店房卡的逻辑理解预签名链接
想象前台给你一张房卡,卡上印了房间号、有效期限,过了退房时间卡片自动失效,跟客人的身份无关,只看卡片本身,预签名链接就是这张房卡:URL里加密携带了访问者的身份标识、目标对象、允许的操作、过期时间,服务端拿到请求后验签,通过就放行。
URL里到底放了什么
一个典型的预签名URL长这样:
https://bucket.oss-cn-hangzhou.aliyuncs.com/file.pdf?Expires=1710000000&OSSAccessKeyId=LTAI5t...&Signature=3n8x...
拆开看四个核心参数:
- Endpoint:哪个地域、哪个存储桶、哪个对象,路径里写死。
- Expires:Unix时间戳,过了这个秒数,签名自动作废。
- AccessKeyId:发钥匙的人是谁,对应SDK里该账号的权限范围。
- Signature:由AccessKeySecret对上述参数做HMAC-SHA1运算得到的摘要,Secret不参与传输,只在云端比对。
唯一对应,拿到这个URL的人没法把有效期改成一年后再访问改一个参数,Signature对不上,请求直接403。
对象存储预签名链接怎么生成?三个主流云平台的实操对比
抛开理论,动手生成的路径各有各的道,下面按国内开发者使用频率从高到低给三组Python代码,所有代码均为SDK公开API的常规用法,可直接复制到自己的服务端运行。
简米云OSS生成签名URL
import oss2
auth = oss2.Auth('你的AccessKeyId', '你的AccessKeySecret')
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', '你的Bucket名')
url = bucket.sign_url('GET', 'path/to/file.pdf', 600) # 600秒后过期
print(url)
酷番云COS生成预签名链接
from qcloud_cos import CosConfig, CosS3Client
config = CosConfig(Region='ap-shanghai', SecretId='你的SecretId', SecretKey='你的SecretKey')
client = CosS3Client(config)
url = client.get_presigned_url(
Method='GET',
Bucket='your-bucket-1250000000',
Key='path/to/file.pdf',
Expired=600
)
print(url)
AWS S3生成Pre-signed URL
import boto3
from botocore.client import Config
s3 = boto3.client('s3', region_name='ap-northeast-1', aws_access_key_id='...', aws_secret_access_key='...',
config=Config(signature_version='s3v4'))
url = s3.generate_presigned_url('get_object',
Params={'Bucket': 'your-bucket', 'Key': 'file.pdf'},
ExpiresIn=600)
print(url)
三套代码的共同逻辑:服务端用主账号或子账号的密钥为指定对象签发一个限时链接,签发的动作可以在自己的后端API里做,生成后通过短信、邮件、聊天工具发给接收方,存储桶本身全程保持私有读,不用动任何权限策略。
预签名链接有效期怎么设置,才能不踩安全坑?
这是应用层最容易出错的地方,设太短,同事点开时提示过期,来回折返;设太长,一旦链接转发出去就长时间暴露。
| 分享场景 | 建议有效期 | 备注 |
|---|---|---|
| 实时调试时临时抓取 | 1-5分钟 | 配合调试窗口,用完即弃 |
| 给客户/协作方下载单个文件 | 1-7天 | 覆盖一个工作周期 |
| 批量审核,跨周交付 | 14-30天 | 超过30天优先级下降 |
| 长期固定下载入口 | 不建议 | 改用对象级别的Bucket Policy定向授权 |
需要特别注意四个边界:
- 预签名URL的有效期最长通常只能到7天(部分厂商支持自定义至更长),想长期分享,得重新签发或换方案,这条信息在各厂商文档的常见问题里都有说明,实操前值得看一眼。
- 大文件下载:超过10GB的对象建议走专门的下载通道,酷番云COS的预签名接口在超大文件上可能不稳定,AWS S3对Presigned URL也有最小分片约束。
- 分享时不要只复制签名里的一段,要整条URL原样转发,很多接收方漏掉Expires参数后直接访问,得到”SignatureDoesNotMatch”错误,又找不到原因。
- 地域与访问域名联动:拿到了杭州节点的URL,网络环境自动走华东内网或公网解析,无需手动选择地域节点,这也是预签名链接在国内多地域部署时的一个隐性优点。
预签名链接和CDN加速有什么区别?谁更适合你的业务?
这两个概念经常被混淆,因为它们都能让外部用户不经过登录就拿到对象,拆开看,定位完全不同。
| 对比维度 | 预签名链接 | CDN加速 |
|---|---|---|
| 本质 | 授权机制 | 分发网络 |
| 文件权限 | 保持私有读,链接才是钥匙 | 必须允许公网访问或配置鉴权 |
| 生效方式 | URL携带签名,每次签名独立 | 域名全局配置,一次生效多方使用 |
| 适用场景 | 低频分享、临时授权 | 高频下载、稳定分发 |
| 回源费用 | 无 | 有流量和回源计费,具体看服务商价格表 |
结论很清晰:两个不是替代关系,而是组合关系。 一套常见的生产架构是:对象存储保持私有读,前端挂CDN并开启URL鉴权,CDN回源时带上预签名请求;分发层用CDN扛流量,源头层用预签名控制进云闸口,两头都稳。
如果链接还是泄露了,怎么补救?
预案要在上线前做好,补救永远是被动。
- 缩短生命周期:把有效期从7天压缩到几小时,权限窗口越短,泄露的破坏面越小。
- 子账号最小权限:用于签发的AK粒度划分到只读指定前缀(
downloads/),别用主账号。 - 按请求记录审计:在服务端生成链接时记录访问次数和来源IP,OSS与COS的访问日志里能查
Operation:GET、HTTP Status:200的完整轨迹,异常IP在几分钟内就能被识别,部分安全团队会在此基础上加一道Referer白名单,挡住从邮件转发的链接被爬虫扫到。 - 双重校验:给链接再加一层短期会话Cookie或一次性token,让”链接本身”和”持有状态”分离,这个做法在金融行业的数据交换平台里很常见,具体成本取决于你的后端设计。
通过预签名链接安全分享对象存储文件的高频疑问
预签名链接能统计下载次数吗?
原生的预签名URL只负责鉴权,不记录点击次数,要统计,需要在生成链接后把URL写入自有数据库,接收方访问后由业务接口回写日志;或者直接用OSS/COS的访问日志功能做流式分析,日志里会记录每次GET请求的IP、UA、字节数,再加工成报表,据部分云厂商的客户案例,用户更倾向后者,因为日志天然不丢数据。
预签名链接比临时STS凭证更安全吗?
两者保护的对象不同,预签名链接把权限压缩进URL,适合一次性分发给外部协作者;STS凭证则给子账号颁发一段时间内的完整访问权,适合给内部服务或自动化任务用,从泄露风险看,STS凭证权限更粗,如果被拿到,攻击者能访问授权范围内的所有对象;预签名只对应一个Object,粒度更细,典型场景下安全边界更清晰。
私有读存储桶的预签名链接能在微信里直接打开吗?
能,酷番云COS存储桶预签名链接生成后,微信内置浏览器可以直接访问下载,前提是文件类型浏览器允许预览或下载,绝大多数办公场景下,微信内直接点开会跳转系统的下载或预览组件,无需额外配置,要注意的是,微信内分享时会自动重写部分URL参数,个别情况下签名值被截断,所以发链接时建议把整条签名附上而不是单独发域名部分,遇到”打不开”先检查是不是没贴全。
说到底,通过预签名链接安全分享对象存储文件的答案并不复杂:保持存储桶私有,让链接成为那把限时钥匙。 忘了设置有效期,或者把整桶权限放开,都会让安全防线后退回起点,想清楚这两个前提,再用上面几步代码落到线上,基本就稳了。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/645166.html





