阿里云储存OSS(服务端签名后前端直传)

流程介绍

在这里插入图片描述本示例中,Web端向服务端请求签名,然后直接上传,不会对服务端产生压力,而且安全可靠。但本示例中的服务端无法实时了解用户上传了多少文件,上传了什么文件。如果想实时了解用户上传了什么文件,可以采用服务端签名直传并设置上传回调。

落地实现

添加依赖

 <!--OSS SDK-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>

步骤一、后端签名加密

@RestController
public class OSSController {
    @CrossOrigin //解决跨域
    @RequestMapping("/oss/policy")
    public Map<String,String> policy(@RequestParam("fileName") String fileName){
        String accessId = ""; // 请填写您的AccessKeyId。
        String accessKey = ""; // 请填写您的AccessKeySecret。
        String endpoint = "oss-cn-beijing.aliyuncs.com"; // 请填写您的 endpoint。
        String bucket = ""; // 请填写您的 bucketname 。
        String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint



        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String date = simpleDateFormat.format(new Date());

        String dir = "tuling-test/"+date+"/"; // 用户上传文件时指定的前缀。


        //文件名生成
        fileName = UUID.randomUUID().toString() + fileName.substring(fileName.lastIndexOf("."));
        String key = dir + fileName;

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessId, accessKey);
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            // PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
            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);

            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);//您的AccessKeyId。
            respMap.put("policy", encodedPolicy);//Policy规定了请求表单域的合法性。
            respMap.put("signature", postSignature);//根据AccessKey Secret和Policy计算的签名信息,OSS验证该签名信息从而验证该Post请求的合法性。
            respMap.put("dir", dir); //前缀
            respMap.put("host", host); // "https://" + bucketname + '.' + endpoint;  (前端请求oss服务路径)
            respMap.put("key", key); //dir + fileName (上传Object的名称。)
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            // respMap.put("expire", formatISO8601Date(expiration));
            return respMap;
        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return null;
    }
}

步骤二、配置客户端

<template>
  <div id="upload">
    <el-upload
      class="upload-demo"
      :action="objectData.host"
      :before-upload="getPolicy"
      :data="objectData"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :file-list="fileList"
      list-type="picture">
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
    </el-upload>
  </div>

</template>

<script>
import {request} from '../network/request'
import axios from "axios";
export default {
  name: "upfile",
  data() {
    return {
      fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}],
      objectData: {
        OSSAccessKeyId: "",
        policy: "",
        Signature: "",
        key: "",
        host: '',
        dir: ''
      }

    };
  },
  created() {

  },
  methods: {
    handleRemove(file, fileList) {
      console.log(file, fileList);
    },
    handlePreview(file) {
      console.log(file);
    },
    getPolicy(file){
      console.log(file)
      const _this = this;
      return new Promise(((resolve, reject) => {
        request({
          url: 'oss/policy',
          params: {
            fileName: file.name
          }
        })
          .then(res=>{
          _this.objectData.OSSAccessKeyId = res.data.accessid; // Bucket拥有者的AccessKey ID。
          _this.objectData.policy = res.data.policy; //Policy规定了请求表单域的合法性。
          _this.objectData.Signature = res.data.signature;//根据AccessKey Secret和Policy计算的签名信息,OSS验证该签名信息从而验证该Post请求的合法性。
          _this.objectData.dir = res.data.dir;//前缀
          _this.objectData.host = res.data.host;// "https://" + bucketname + '.' + endpoint;  (前端请求oss服务路径)
          //_this.objectData.key = res.data.dir + "${filename}";
          _this.objectData.key = res.data.key;//dir + fileName (上传Object的名称。)
          _this.fileList.push({name: res.data.key,url: res.data.host+"/"+res.data.key})
          resolve(true);
        })
        .catch(err=>{
          console.log(err);
          reject(false);
        })
      }))
    }
  }
}

</script>

<style scoped>
#upload{
  width: 400px;
}
</style>

步骤三、修改CORS

客户端进行表单直传到OSS时,会从浏览器向OSS发送带有Origin的请求消息。OSS对带有Origin头的请求消息会进行跨域规则(CORS)的验证。因此需要为Bucket设置跨域规则以支持Post方法。

  1. 登录OSS管理控制台。
  2. 单击Bucket列表,之后单击目标Bucket名称。
  3. 单击权限管理 > 跨域设置,在跨域设置区域单击设置。
  4. 单击创建规则,配置如下图所示。
    在这里插入图片描述
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值