当前位置: 首页 > Web前端 > HTML

本文将带你了解对象存储OSS前端直传的使用方法,如果你不明白,再读一遍!(武士)

时间:2023-03-28 01:11:02 HTML

原因是有时候在项目中,比如上传文件,一般都是后台提供接口,然后我们上传的时候,后台发送给阿里OSS或者其他服务商进行对象存储,然后取最后的url来保存或者返回给前端,这种方式在图片上传频率不高的业务场景下可能问题不大,但是如果你的项目是相册或者资源提供者,总之就是上传非常频繁如果是文件的话,服务器的带宽可能有点吃不消,那么有没有更好的解决办法呢?服务器端签名,客户端直传事实上,阿里巴巴、腾讯、七牛等云服务商都提供了类似于阿里巴巴的STS(SecurityTokenService)的临时访问权限管理服务。本次我们以阿里云为例,给大家介绍一下如何使用STSToken在服务端对STStoken进行签名,然后提供给前端,让前端直接使用这个Token将文件直接签名到阿里云服务器,获取STStoken。我们直接使用Node.js作为。比如其他语言的服务可以在阿里云SDK参考(STS)文档中找到,包括Python、Java……首先,我们需要安装一个sts的npm包——sdk:@alicloud/sts-sdk(Nodejsversion>=8.5.0)npminstall@alicloud/sts-sdk然后我们在utils中新建一个文件oss-sts-server.js生成STSToken供前端使用(这只是一个例子,后面可以自己封装)constStsClient=require('@alicloud/sts-sdk');/***生成STStoken*@paramaccessKeyIdAccessKeyID*@paramaccessKeySecret临时访问密钥AccessKeySecret获取来自STS服务*@paramroleArn指定角色的ARN*@paramroleSessionName是临时Token的session名称,可以自己指定,用来标识你的用户,或者区分Token发给谁*@paramdurationSecondstoken有效事件,单位:秒*@parampolicy指定的授权策略,默认为null*@return*RequestId,请求id*AssumedRoleUser:{*Arn,${roleArn}/${roleSessionName}*AssumedRoleId*},*Credentials:{*SecurityToken,ststoken*AccessKeyId,accessKeyId*AccessKeySecret,accessKeySecret*Expiration过期时间*}*/exportdefaultfunctiongenerateSTSToken(accessKeyId,accessKeySecret,roleArn,roleSessionName='external-username',durationSeconds=3600,policy=null){conststs=newStsClient({endpoint:'sts.aliyuncs.com',//从sts控制台检查accessKeyId,//阿里云控制台查看accessKeySecret//阿里云控制台查看});returnres=awaitsts.assumeRole(roleArn,roleSessionName,policy,durationSeconds);我解释一下这个generateSTSToken函数的入参,通常我们在使用阿里云或者腾讯云的时候,一般都会开一个RAM账号,也就是子账号。我们使用子账号登录阿里云后台后,进入对象存储(OSS)控制台页面,找到安全令牌(子账号授权),也就是下图标注的地方,点击进入上面的RAMConsole按钮,然后点击StartAuthorization按钮,然后就可以得到accessKeyId,accessKeySecret,roleArn,roleSessionName和默认过期时间DurationSeconds,如下图,由于我之前授权过一次,所以会有左下角的提示。这些参数一定要保存好,不能泄露。一旦泄露,请修改RAM账号的密码,重新生成,让之前的密码失效。改进服务器提供的数据。这时候accessKeyId、accessKeySecret、stsToken、expiration这四个参数其实已经拿到了,但是客户端还需要buckets:对象存储的命名空间和region:bucket所在区域的两个参数。这个bucket其实就是对应使用的bucket。这可以在阿里云对象存储页面上看到。有个bucketlist,就是你用的bucket的名字。region就是某个bucket我所在的region,比如我的是oss-cn-beijing。这个时候服务端的工作已经完成,可以在前端提供接口了。认证通过后,会将这些参数返回给前端。接下来,让我们把舞台交给我们的前端~{accessKeyId,accessKeySecret,stsToken,bucket,region,expiration}前端的工作完成了,我们后端同学的工作也完成了~前端-enders们,来我左边画一条龙,你右边画一条龙彩虹(bushi)首先我们也新建一个oss-sts-client.js/ts,然后安装一个ali-sdk/ali-oss:AliyunOSS(openstorageservice)JavaScriptSDKforthebrowserandNode.js(github.com)package,顺便说一句,它不支持IE10和以前的IE版本。npminstallali-oss--save然后将以下内容复制到这个文件中。使用js的同学可以删掉ts相关的代码(赶紧转ts好了,没人再跟你玩了)//这是服务端提供给前端的一个请求接口,返回我们上面说的参数import{getOssSTSToken}来自“./request”;//@ts-ignore忽略ts报错,ali-oss很快提供了@types包,文档比较难懂,库没有文档。如果你的文档维护得很好,我还需要写这个吗?我什至不想抱怨...(bushi)importOSSfrom'ali-oss'typeOssStsType={accessKeyId:stringaccessKeySecret:stringstsToken:stringexpiration:number//这个是前端计算出的token过期多少秒region:stringbucket:string}/***获取OSSClient*@paramaccessKeyIdAccessKeyID*@paramaccessKeySecret从STS服务获取的临时访问权限KeyAccessKeySecret*@paramstsToken从STS服务获取的安全令牌(SecurityToken)*@paramregionBucket区域*@parambucketBucket名称*/exportdefaultasyncfunctiongetOssClient(){const{code,data:params}=awaitgetOssSTSToken();如果(代码!==200)返回假;//如果请求失败,向上游处理constclient=newOSS({...params,refreshSTSTokenInterval:params.expiration,//刷新临时访问凭证的时间间隔,单位毫秒。//(这个refreshSTSToken在文档中可以肯定的是,每次上传前可以检查是否过期,不要依赖提供的方法afterexpirationif(code===200){returndata}},})returnclient}好了,至此我们就封装好了这个前端需要在上传文件时调用的方法。前端维护STSToken。首先,我们在前端页面第一次上传文件时,需要调用getOssClient方法获取oss-client的对象实例,然后使用这个实例进行上传。这时候需要判断token是否过期,如果没有如果有过期时间,就用这个实例上传。如果过期,重新生成一个实例!这里以一个简单的小文件上传为例(大文件分片上传,上传成功回调(需要后端同学提供回调地址)。大家可以自行阅读文档,我不会详细介绍)asyncfunctionuploadFileAction(file,client){letnewClient=client;//伪代码://if(!newClient||tokenisexpired){//如果没有实例对象或者token过期,会重新生成//newClient=awaitgetOssClient();//调用我们上面封装的一个方法//}constfilePath='xxx/xxx/'//bucket中的存储路径根据业务需要设置,文件名也可以设置const{res,name,url}=awaitnewClient.put(`${filePath}${file.name}`,file);if(res.status===200){//这里获取上传文件的urlreturnurl}}关于oss-client这里的维护策略,请仁者见仁智者见智。解决方案有很多,如何贴合业务,但不建议将STStoken等参数存储在localStorage、sessionStorage和indexDB中。为什么你确定你的用户不是前端er?CORS问题还没有结束,xdm稍等,上面结束后,如果我们在本地联调的时候不开启代理,还是会出现CORS问题。这个时候我们还需要去服务器配置,找到跨域设置,进去创建规则,检查方法看你用什么,source和allowheaders直接搞定*就完事了麻木到完全麻木,我总结一篇OSS前端直传可以打通前后端进程的文章。如果您有任何问题,请在评论中讨论。如果对您有帮助,请给我们留言。连续三个