阿里云 OSS 公开读(public-read) 的文件默认是任何人都可直接访问的,无法直接在 URL 后加“授权码”来限制访问——因为公开文件的设计就是无鉴权访问。
但你可以通过以下 两种主流方案 实现“带授权码才能访问”的效果:
方案一:改用私有文件 + 生成带签名的临时 URL(推荐 )
这是阿里云官方推荐的安全做法:
原理:将文件权限设为 private(私有)。
通过你的服务端(PHP/Python/Node.js 等)生成一个 带签名的临时 URL,URL 中包含:
过期时间(如 30 分钟后失效)
OSS 签名(相当于“授权码”)
用户访问这个 URL 时,OSS 验证签名和时间,合法则返回文件。
生成带签名 URL 的示例(Python):from datetime import datetime, timedelta
from aliyunsdkcore.client import AcsClient
from aliyunsdkoss.request.v20190517 import GeneratePresignedUrlRequest
# 或更简单:使用 oss2 SDK
import oss2
auth = oss2.Auth('<your-access-key-id>', '<your-access-key-secret>')
bucket = oss2.Bucket(auth, 'https://oss-cn-beijing.aliyuncs.com', 'your-bucket-name')
# 生成 30 分钟有效的下载链接
url = bucket.sign_url('GET', 'path/to/your/file.jpg', expires=1800)
print(url)
# 输出示例:
# https://your-bucket.oss-cn-beijing.aliyuncs.com/file.jpg?OSSAccessKeyId=xxx&Expires=1712345678&Signature=abc123... 优点:
安全,签名有时效
无需改动文件权限
支持任意文件(即使原本是私有的)
注意:URL 本身不是“在原公开 URL 后加授权码”,而是一个全新的带参数的 URL。
方案二:保留公开文件 + 自建反向代理(带 Token 验证)
如果你必须保持文件公开(比如已大量分发公开链接),又想加一层授权,可以用:
原理:你的服务器(如 Nginx / PHP / Node.js)作为反向代理。
用户访问:https://your-domain.com/download?file=xxx&token=SECRET123
你的服务端验证 token:
正确 → 用 302 重定向 或 流式代理 转发到 OSS 公开 URL
错误 → 返回 403
Nginx 示例(简易版):
location /download {
# 验证 token(简单示例,实际建议用服务端逻辑)
if ($arg_token != "your_hardcoded_token") {
return 403;
}
# 重定向到 OSS 公开地址
return 302 https://your-bucket.oss-cn-beijing.aliyuncs.com/$arg_file;
} 缺点:
增加服务器负担(所有流量经过你的服务器)
重定向后用户仍能看到真实 OSS 公开 URL(可被绕过)
token 写死不安全,需动态生成
适用场景:临时方案、内部系统、对安全性要求不高的场景。
不可行的方案(常见误区)
| 在公开 URL 后加 ?auth=xxx | OSS 公开文件忽略所有 query 参数,直接返回内容 |
| 用 OSS 的“自定义域名 + 回源鉴权” | 这是给CDN回源用的,不是给终端用户鉴权 |
| 修改 Bucket Policy 加 IP 限制 | 不能实现“授权码”逻辑,且用户 IP 多变 |
最佳实践建议
| 安全分发文件,控制访问权限 | 方案一:私有文件 + 签名 URL |
| 已有大量公开链接,临时加验证 | 方案二:反向代理 + Token 验证(短期过渡) |
| 需要永久有效但带密码的链接 | 不推荐,应改用短期签名 URL |
安全提醒
永远不要把 AccessKey 写在前端代码中!
签名 URL 的 expires 时间尽量短(如 5~30 分钟)。
如果用方案二,不要把 token 写死在 Nginx 配置中,应由后端动态验证(如 JWT、数据库 token)。
网友回复


