The front end is directly transmitted to Alibaba Cloud OSS through STS (including file upload, download and automatic refresh of stsToken)

Preface

Recently, the project business needs to implement a resource management function, so I simply learned how to use Alibaba Cloud OSS on the front end.

Originally, these things were implemented on the backend, but this method has many shortcomings. For example, file upload needs to be done twice, first uploaded to the backend, and then uploaded from the backend to Alibaba Cloud OSS, which takes up bandwidth and wastes time; in addition, The front-end cannot get the real upload progress yet. It can only know the progress of uploading to the back-end. As a result, it will take some time to see the file after it is uploaded, especially when the file is relatively large.

If you can directly upload files to Alibaba Cloud OSS on the front end, then the above problems will be solved. But there is another security issue at this time. AccessKeyId and accessKeySecret are needed when uploading. If they are placed in the front-end code, they can be easily leaked and stolen. Obviously, the official is also aware of this problem, so it provides another way, using STS for temporary authorization, the advantages are as follows:

  1. You don't need to disclose your long-term key (AccessKey) to the third-party application, just generate an access token and give the token to the third-party application. You can customize the access rights and expiration date of this token.
  2. You don't need to care about permission revocation, and the access token will automatically become invalid after it expires.

In this way, there is no need to put important keys on the front end, and the job of the back end is to return these tokens for use by the front end. Even if they are exposed, there will be a validity period, and the security factor is greatly improved. I won’t talk about the backend part because I’m not responsible for it (well, I don’t know the backend either), you can refer to the official documentation for details . Alibaba Cloud creates user roles and authorization policies, which can also be found in official documents, so I won’t introduce them here.

download

First you need to download the Alibaba Cloud OSS sdk:

npm install ali-oss

encapsulation

import OSS from 'ali-oss' // 引入依赖
import {
    
     getOSSToken } from '@/api/app/xxx' // 后端接口,获取临时凭证

// 生成client
export async function getAliOssClient() {
    
    
  const data = await getOSSToken()// 获取凭证
  const parseMast = {
    
    
    bucket: data.bucketName, // bucket名称
    region: data.endpoint.split('.')[0], // 地域
    accessKeyId: data.accessKeyId,
    accessKeySecret: data.accessKeySecret,
    stsToken: data.securityToken,
    expiration: data.expiration, // 有效期
    refreshSTSToken: async() => {
    
     // 刷新临时访问凭证的回调,在上传大文件的时候会用到
      const info = await getOSSToken()
      return {
    
    
        accessKeyId: info.accessKeyId,
        accessKeySecret: info.accessKeySecret,
        stsToken: info.securityToken
      }
    },
    // 刷新临时访问凭证的时间间隔,单位为毫秒,在过期前一分钟刷新
    // 过期时间是后端配的,这里配合后端把时间写死也可以,例如 15 分钟过期,10 分钟就可以刷新一次
    refreshSTSTokenInterval: new Date(data.expiration) - new Date() - 1000 * 60
  }
  return new OSS(parseMast) // 调用OSS依赖
}

// 下载文件
export async function downloadFromAliOss(fileName) {
    
    
  const client = await getAliOssClient()
  const response = {
    
    
    'content-disposition': `attachment; filename=${
      
      encodeURIComponent(fileName)}`
  }
  const url = client.signatureUrl(fileName, {
    
     response })
  const a = document.createElement('a')
  a.style.display = 'none'
  a.href = url
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}

In fact, the uploaded file part can also be encapsulated, but since the uploaded file involves other variables, too many parameters are passed when encapsulated, so I am too lazy to encapsulate it - - it can be decided according to business needs.

use

// 将文件流上传oss
async onSubmit() {
    
    
  for (const item of this.fileList) {
    
    
    item.client = await getAliOssClient(this.appId)
    this.$set(item, 'percentage', 0)
    // 自定义文件名路径,如果要上传到特定的目录,需要将前缀也带上
    // 例如 fileName 为 '/a/b/c/test.txt',会将 test.txt 上传到对应目录下
    const fileName = this.uploadPath + item.name
    // 请求oss接口上传
    // 分片上传
    item.client.multipartUpload(fileName, item.raw, {
    
    
      parallel: this.parallel, // 并发数量,一般是 4
      partSize: this.partSize, // 分片大小,一般是 1M,也就是 1024 * 1024
      progress: async(p, checkpoint) => {
    
     // 监听上传事件
        await this.onUploadProgress(item, p, checkpoint)
      },
      timeout: 120000 // 2分钟超时
    }).then((response) => {
    
    
      // console.log(response);
    }).catch((error) => {
    
    
      this.$set(item, 'myStatus', 'failed')
      console.log(error)
    })
  }
},
// 上传事件
async onUploadProgress(item, p, checkpoint) {
    
    
  if (checkpoint) {
    
    
    this.checkpoints[checkpoint.uploadId] = checkpoint // 保留分片,可以做断点续传,这部分暂时没有实现,可以参照网上的做法,或者官方文档
    item.upload = checkpoint.uploadId
  }
  // 上传进度
  item.percentage = Number((p * 100).toFixed(2))
},
// 取消上传
onCancelUpload(item, index) {
    
    
  item.client.cancel()
  this.fileList.splice(index, 1)
}

During this process, various problems may arise, but you can basically find solutions in the FAQs in the official documents . Most of the problems you encounter are cross-domain and authorization policy problems. Just configure them.
Reference:
Alibaba Cloud OSS official document
Vue front-end is directly transmitted to Alibaba Cloud OSS (supports breakpoint resume upload, multi-part upload, batch upload)
If you have any questions, please feel free to discuss~

Guess you like

Origin blog.csdn.net/weixin_45732455/article/details/132105119