服务端签名直传是唯一安全可行的路径,因使用临时凭证避免泄露长期密钥;需三步:配置OSS(建Bucket并设CORS)、服务端调STS获取临时凭证并生成带Policy的签名、Web端用HTML表单提交。
直接用服务端签名直传,别在前端硬塞
和
—— 这是唯一安全可行的路径。其他方式要么泄露密钥,要么绕远路拖慢上传,没有折中。
为什么不能用 Browser.js SDK 直传
因为它的签名逻辑必须把
和
暴露在前端 JS 里。哪怕加混淆、加动态拼接,只要运行在浏览器,就等于公开广播。实际抓包或反编译几秒就能还原出完整凭证。
一旦泄露,攻击者可任意读写你整个 Bucket,甚至调用 STS 接口生成更长期权限
阿里云
控制台明确标红警告:“不推荐在前端使用永久 AK/SK”
即使加了 Referer 白名单或 IP 限制,也挡不住已拿到凭证的恶意请求
PostObject 签名必须带 Policy 且严格校验条件
是 Web 表单直传的核心接口,它不接受 URL 签名,只认 base64 编码的
和对应
。Policy 不是可选字段,而是强制校验上传行为边界的策略文档。
必须包含
(ISO8601 格式时间戳,不是秒数)和
数组
常见误写:
漏掉末尾斜杠,导致上传到
也被放行
必须校验文件大小:
(0–20MB),否则可能被用于 DoS 攻击
不要在
里写死
,前端跳转不可控,应由 OSS 回调(callback)或后端轮询处理结果
PHP 生成签名时要注意的三个硬坑
很多 PHP 示例代码直接抄 Node.js 版本,但 PHP 的
默认输出二进制,而 OSS 要求的是 Base64 编码后的字符串;同时时间格式、换行符、JSON 编码细节稍错一点,签名就失效。
阿里云AI平台
阿里云AI平台
下载
立即学习
“
PHP免费学习笔记(深入)
”;
Policy 字符串必须用
,否则中文路径或特殊字符会导致签名不匹配
计算 signature 前,Policy 必须先做
,再用
,最后再
—— 少一层 encode 就 403
服务端返回给前端的
必须是
(比如
),不能是控制台看到的“外网访问域名”,也不能漏掉
前端表单提交必须用 multipart/form-data 且字段顺序固定
OSS 对表单字段顺序有隐式要求:必须把
、
、
、
、
等放在文件字段
之前。顺序错乱会导致 400 错误,但错误信息里不提示具体哪错。
HTML 表单
的 name 必须严格匹配文档:
、
、
、
、
、
(如启用)
建议设为
,这样上传成功后响应体是 XML,前端可直接解析
字段获取最终路径
不要用
或
模拟表单提交 —— 它们无法构造真正的
边界,必须用原生
提交或 FormData +
最易被忽略的是:CORS 配置必须允许
方法、
头、以及你前端实际使用的 Origin(比如
),缺一不可;而很多人只配了
,却忘了
和
选项冲突,导致签名请求被浏览器拦截。
AccessKeyIdAccessKeySecretAccessKeyIdAccessKeySecretPostObjectpolicysignaturepolicyexpirationconditions['starts-with', '$key', 'uploads/']uploads123.jpg['content-length-range', 1, 20971520]conditions$success_action_redirecthash_hmacjson_encode($policy, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)base64_encode()hash_hmac('sha1', $policyBase64, $accessKeySecret, true)base64_encode()hosthttps://. https://my-bucket.oss-cn-hangzhou.aliyuncs.comhttps://keypolicysignatureOSSAccessKeyIdsuccess_action_statusfilekeypolicysignatureOSSAccessKeyIdsuccess_action_statuscallbacksuccess_action_status201fetchXMLHttpRequestmultipart/form-datasubmit()POSTContent-Typehttps://your-app.com*Access-Control-Allow-Credentials: truecredentials