跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

PHP OSS存储怎么接_PHP对接阿里云OSS与文件直传签名生成【生成】

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

相关文章