对象存储OSS:在客户端直接上传文件到OSS
客户端直传是指客户端直接上传文件到对象存储OSS。相对于服务端代理上传,客户端直传避免了业务服务器中转文件,提高了上传速度,节省了服务器资源。本文介绍客户端直传的方案优势、安全实现和实践参考。
在典型的服务端和客户端架构下,常见的文件上传方式是服务端代理上传:客户端将文件上传到业务服务器,然后业务服务器将文件上传到OSS。在这个过程中,一份数据需要在网络上传输两次,会造成网络资源的浪费,增加服务端的资源开销。为了解决这一问题,您可以在客户端直连OSS来完成文件上传,无需经过业务服务器中转。
实现客户端直传需要解决以下两个大问题:
上传文件到OSS需要使用RAM用户的访问密钥(AccessKey)来完成签名认证,但是在客户端中使用长期有效的访问密钥,可能会导致访问密钥泄露,进而引起安全问题。为了解决这一问题,您可以选择以下方案实现安全上传:
服务端生成STS临时访问凭证
服务端生成PostObject所需的签名和PostPolicy
服务端生成PutObject所需的签名URL
客户端向业务服务器请求临时访问凭证。
业务服务器使用STSSDK调用AssumeRole接口,获取临时访问凭证。
STS生成并返回临时访问凭证给业务服务器。
业务服务器返回临时访问凭证给客户端。
客户端使用OSSSDK通过该临时访问凭证上传文件到OSS。
OSS返回成功响应给客户端。
服务端示例代码
服务端生成临时访问凭证的示例代码如下:
当前代码支持一键部署,您可以直接在函数计算FC中一键部署本代码。oss-upload-sts-app
Web端使用临时访问凭证上传文件到OSS的示例代码如下:
客户端向业务服务器请求Post签名和PostPolicy等信息。
业务服务器生成并返回Post签名和PostPolicy等信息给客户端。
客户端使用Post签名和PostPolicy等信息调用PostObject通过HTML表单的方式上传文件到OSS。
服务端生成Post签名和PostPolicy等信息的示例代码如下:
当前代码支持一键部署,您可以直接在函数计算FC中一键部署本代码。oss-upload-post-signature-app
Web端使用Post签名和PostPolicy等信息上传文件到OSS的示例代码如下:
客户端向业务服务器请求签名URL。
业务服务器使用OSSSDK生成PUT类型的签名URL,然后将其返回给客户端。
客户端使用PUT类型的签名URL调用PutObject上传文件到OSS。
OSS向客户端返回成功响应。
服务端生成签名URL的示例代码如下:
当前代码支持一键部署,您可以直接在函数计算FC中一键部署本代码。oss-upload-presigned-url-app
Web端使用签名URL上传文件到OSS的示例代码如下:
constform=document.querySelector("form");form.addEventListener("submit",(event)=>{event.preventDefault();constfileInput=document.querySelector("#file");constfile=fileInput.files[0];fetch("/get_presigned_url_for_oss_upload",{method:"GET"}).then((response)=>{if(!response.ok){thrownewError("获取预签名URL失败");}returnresponse.text();}).then((url)=>{fetch(url,{method:"PUT",headers:newHeaders({"Content-Type":"image/png",}),body:file,}).then((response)=>{if(!response.ok){thrownewError("文件上传到OSS失败");}console.log(response);alert("文件已上传");});}).catch((error)=>{console.error("发生错误:",error);alert(error.message);});});