600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 【OSS】服务端签名后直传实现阿里云存储上传文件

【OSS】服务端签名后直传实现阿里云存储上传文件

时间:2022-12-28 11:27:44

相关推荐

【OSS】服务端签名后直传实现阿里云存储上传文件

文章目录

1、前言2、阿里云OSS2.1、开通服务2.2、创建Bucket2.3、创建子账户 3、服务端3.1、依赖导入3.2、配置文件3.3、控制器编写3.4、接口测试 4、前端联调4.1、组件编写4.2、开启跨域访问4.3、整体测试

1、前言

阿里云对象存储**OSS(Object Storage Service)**是一款海量、安全、低成本、高可靠的云存储服务,这也是我们开发过程中较为常用的一个服务。Web端常见的上传方法是用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传到OSS。

而在这里则是基于Post Policy(用户表单上传的策略)的使用规则在服务端完成签名,然后通过表单直传数据到OSS。由于服务端签名直传无需将AccessKey暴露在前端页面,相比JavaScript客户端签名直传具有更高的安全性

参考文档:

Aliyun Spring Boot OSS Simple服务端签名直传并设置上传回调示例

另外一种接收文件集合上传返回图片链接的上传方式:【OSS】SpringBoot搭配线程池整合阿里云OSS实现图片异步上传

2、阿里云OSS

2.1、开通服务

进入到阿里云控制台,打开左上角的菜单选中对象存储OSS(找不到的可以在产品与服务中搜索)

2.2、创建Bucket

在开通OSS对象存储服务之后,点击新建Bucket,填写自己的Bucket Name和地狱,优先选择靠近自己所在地的,完成设置之后确认即可记得这里保存后弹出来的界面的概览的访问域名的外网访问的Endpoint(地域节点)

下面是我个人的一个选项参数供大家参考(个人用途为项目存储图片):

存储类型:低频访问存储,因为为个人练手项目,因此不需要很高的访问量;HDFS服务:不搞,穷得叮当响;同城冗余存储:不搞,穷得叮当响;版本控制:不搞,穷得叮当响;读写权限:公共读,方便访问,但是不要开公共读写;服务端加密方式:不搞,穷得叮当响;实时日志查询:不搞,穷得叮当响。

2.3、创建子账户

创建子账户获取AccessKey IDAccessKey Secret。这一操作在鼠标停顿在右上角头像 -> AccessKey管理(前提是进入控制台之后头像才会有这一菜单)。

在里面创建用户,选中Open API之后确认,会提示你进行认证,这里记得记得,AK和AS一定要复制下来保存好,截个图也行,因为你关掉这一信息之后再也找不到AS了。 在用户界面找到创建的子账户,点击添加权限进行分配权限,让它拥有操作OSS的权限。

3、服务端

3.1、依赖导入

在服务端,主要就是对OSS进行一个配置连接,利用阿里云提供的API生成需要的签名。针对这一需求,我们需要导入阿里云OSS云存储依赖,注意的是这里已忽略Spring web、Lombok等依赖。

<dependencies><!-- 略 --><!--阿里云OSS云存储依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alicloud-oss</artifactId><version>2.2.0.RELEASE</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.6.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

3.2、配置文件

为了数据的统一管理,将服务所需数据统一填写在application.yml文件中,同样也可以直接存放在类中,下面是各个属性数据的获取处:

endpoint:地域节点,位于对象存储/Bucket 列表/所创建的Bucket/概览下的访问域名的外网访问的Endpoint(地域节点);bucket:所创建的Bucket名;access-key:创建子账户时生成的AK,如果前面保存了可直接cv,没有的话也可前往子账户界面进行查看;secret-key:创建子账户时生成的AS,只能前面保存然后进行cv,没有保存的话需重新创建子账户。

# 指定端口号server:port: 8808spring:# 服务名称application:name: 你的服务名称# OSS配置cloud:alicloud:oss:endpoint: 你的地域节点bucket: 你的Bucket名access-key: 你的AKsecret-key: 你的AS

3.3、控制器编写

在controller包下新建OssController类,在其中编写生成签名等信息的相关操作。

@RestController@RequestMapping("/oss")public class OssController {@AutowiredOSS ossClient;@Value("${spring.cloud.alicloud.oss.endpoint}")String endpoint;@Value("${spring.cloud.alicloud.oss.bucket}")String bucket;@Value("${spring.cloud.alicloud.access-key}")String accessId;@Value("${spring.cloud.alicloud.secret-key}")String accessKey;@GetMapping("/policy")public Result policy() {// host的格式为 bucketname.endpoint,即https://你的bucket名.地域节点/文件名.文件后缀String host = "https://" + bucket + "." + endpoint;// 用户上传文件时指定的前缀,即存放在以时间命名的文件夹内String dir = new SimpleDateFormat("yyyy-MM-dd").format(new Date());Map<String, String> respMap = null;try {// 过期时间long expireTime = 30;long expireEndTime = System.currentTimeMillis() + expireTime * 1000;Date expiration = new Date(expireEndTime);PolicyConditions policyConds = new PolicyConditions();policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);// 生成签名String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);byte[] binaryData = postPolicy.getBytes("utf-8");String encodedPolicy = BinaryUtil.toBase64String(binaryData);String postSignature = ossClient.calculatePostSignature(postPolicy);respMap = new LinkedHashMap<String, String>();// AKrespMap.put("accessid", accessId);// 用户表单上传的策略(Policy)respMap.put("policy", encodedPolicy);// 签名respMap.put("signature", postSignature);// 上传文件时指定的前缀respMap.put("dir", dir);// oss保存文件的hostrespMap.put("host", host);// 过期时间respMap.put("expire", String.valueOf(expireEndTime / 1000));} catch (Exception e) {// Assert.fail(e.getMessage());System.out.println(e.getMessage());} finally {// 关闭oss客户端流ossClient.shutdown();}return Result.ok().put("data", respMap);}}

3.4、接口测试

由于请求的方式为Get,因此可以直接使用浏览器,或使用Postman、Apifox等接口测试工具进行测试,这里使用的是Apifox,请求http://localhost:8808/oss/policy

4、前端联调

4.1、组件编写

这里使用到的前端技术为Vue+Element-UI,这里只提供了单独的文件上传组件,大家自行导入使用即可,但是记得下载Element-UI以及UUID的依赖包。注意的是上传组件中的action需要你创建的Bucket中的Bucket域名,这个和地域节点获取的地方一致

<template> <div><el-uploadaction="你创建的Bucket中的Bucket域名,xu":data="dataObj"list-type="picture":multiple="false" :show-file-list="showFileList":file-list="fileList":before-upload="beforeUpload":on-remove="handleRemove":on-success="handleUploadSuccess":on-preview="handlePreview"><el-button size="small" type="primary">点击上传</el-button><div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过10MB</div></el-upload><el-dialog :visible.sync="dialogVisible"><img width="100%" :src="fileList[0].url" alt=""></el-dialog></div></template><script>export default {name: 'singleUpload',props: {value: String},computed: {imageUrl() {return this.value;},imageName() {if (this.value != null && this.value !== '') {return this.value.substr(this.value.lastIndexOf("/") + 1);} else {return null;}},fileList() {return [{name: this.imageName,url: this.imageUrl}]},showFileList: {get: function () {return this.value !== null && this.value !== ''&& this.value!==undefined;},set: function (newValue) {}}},data() {return {// 封装服务端返回的数据dataObj: {policy: '',signature: '',key: '',ossaccessKeyId: '',dir: '',host: '',},dialogVisible: false};},methods: {emitInput(val) {this.$emit('input', val)},handleRemove(file, fileList) {this.emitInput('');},handlePreview(file) {this.dialogVisible = true;},beforeUpload(file) {console.log(file.size);let _self = this;return new Promise((resolve, reject) => {// 这里使用了封装的请求方式,可以直接换成axios即可http({url: http.adornUrl("/oss/policy"),method: "get",params: http.adornParams({})}).then(response => {console.log("响应的数据",response);_self.dataObj.policy = response.data.policy;_self.dataObj.signature = response.data.signature;_self.dataObj.ossaccessKeyId = response.data.accessid;// 存放进oss的命名格式为uuid+原本文件名_self.dataObj.key = response.data.dir + '/' + getUUID()+'_${filename}';_self.dataObj.dir = response.data.dir;_self.dataObj.host = response.data.host;resolve(true)}).catch(err => {reject(false)})})},handleUploadSuccess(res, file) {console.log("上传成功...")this.showFileList = true;this.fileList.pop();this.fileList.push({name: file.name, url: this.dataObj.host + '/' + this.dataObj.key.replace("${filename}",file.name) });this.emitInput(this.fileList[0].url);}}}</script><style></style>

4.2、开启跨域访问

这时候功能按道理来说其实都是可以正常运行的了,只是在前端测试的时候会出现CORS跨域问题。这时因为客户端进行表单直传到OSS时,会从浏览器向OSS发送带有Origin的请求消息。OSS对带有Origin头的请求消息会进行跨域规则(CORS)的验证。因此需要为Bucket设置跨域规则以支持Post方法。

登录OSS管理控制台。单击Bucket列表,然后单击目标Bucket名称。在左侧导航栏,选择****权限管理** > *跨域设置*,然后在跨域设置区域,单击设置**。单击创建规则,配置如下图所示,确认即可。

4.3、整体测试

将前端项目和后端项目都跑起来之后,我们来到前端界面进行上传测试,下面是测试结果:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。