amazon S3 API 對minio對象存儲服務器進行簽名直傳 (vue+java簽名直傳)

普通上傳:

1:前端上傳到後端(後端服務器帶寬限制,極大影響性能)

2:後端保存到文件服務器(同步/異步)

3:後端保存到數據庫

簽名直傳:

1:前端從後端獲取簽名

2:前端根據簽名上傳到文件服務器(不走後端)

3:前端返回後端URL保存到數據庫

首先保障文件上傳服務可以使用

可以搭建一個Minio服務器

docker run -p 9000:9000 --name minio1 \
>   -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
>   -e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
>   -v /mnt/data:/data \
>   -v /mnt/config:/root/.minio \
>   minio/minio server /data

使用過程中出現的坑總結(沒有問題忽略下面兩條)

1:minio上傳大文件錯誤

413:Request Entity Too Large

原因

文件太大超Ingress限制

解決

創建 ingress 時添加 annotations(註釋)

metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 1024m

2:
一般bucket公共讀的是不需要添加後綴就可以訪問,一般私有的bucket是需要添加的後綴。
出現了奇怪的問題:添加後綴不可以訪問,不添加後綴反而可以訪問
排查:兩處問題:
1: bucket權限錯誤,設成共有的了(需要私有)
2:獲取簽名出錯
看了看代碼objectClient().getSignedURL方法出錯

簽名直傳

首先,前端調用後端接口獲取簽名

簽名直傳後端:

    public ResultModel getObsSign(@RequestParam Map<String, String> paramMap) {
        ResultModel resultModel = new ResultModel();
        int defaultTTLSeconds = 60 * 60;
        Long maxLength = 100 * 1024L;
        PostPolicyRequest postPolicyRequest = new PostPolicyRequest(defaultTTLSeconds, maxLength, obsAttributeConfig.getBucket());
        PostPolicyInfo postPolicyInfo = objectClient.generatePostPolicy(postPolicyRequest);
        resultModel.setData(postPolicyInfo);
        return resultModel;
    }

拿到簽名信息後,爲了確保正確,可以在cmd中進行測試

curl -X POST http://minio.glodon.com/bkqw \
  -H 'content-type: multipart/form-data' \
  -F 'key=2.txt' \
  -F policy=eyJleHBpcmF0aW9uIjoiMjAyMC0wMi0wNVQyMzoxNTo0OC4wMTZaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTAwMDBdLHsiYnVja2V0IjoiYmtxdyJ9LHsic3VjY2Vzc19hY3Rpb25fc3RhdHVzIjoiMjAwIn0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCIiXV19 \
  -F AWSAccessKeyId=AKIAICSFADNN8EXAMBLE \
  -F signature=Ezl5w6g1OJMWjDhxN42IPcSk8WA= \
  -F success_action_status=200 \
  -F 'file=@D:\1.txt'

出現下面響應代表簽名獲得的是沒問題的(注意此處對文件大小的限制)

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   986    0     0  100   986      0   962k --:--:-- --:--:-- --:--:--  962k



前端代碼開發

util.js

import request from '@/utils/request'
// 獲取簽名
export function getSign(applicationId) {
  return request({
    url: '/application/' + applicationId + '/sign',
    method: 'get'
  })
}
// 上傳
export function uploadBySign(params, host) {
  return request({
    url: host,
    method: 'post',
    headers: { 'Content-Type': 'multipart/form-data' },
    data: params
  })
}

上傳圖片

    // 前端選中圖片
    handleChange(file) {
      this.fileList = []
      this.fileList.push(file)
      this.file = file
      const fileFormat = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length)
      if (fileFormat.toLowerCase() !== 'jpg' && fileFormat.toLowerCase() !== 'png' && fileFormat.toLowerCase() !== 'jpeg' && fileFormat.toLowerCase() !== 'svg') {
        this.file = ''
        this.$message.error('僅支持.png .jpg .jpeg格式')
        this.$refs['my-upload'].clearFiles()
        this.fileList = []
        return
      }
      var obsData = new FormData()
      obsData.append('key', this.file.name)
      obsData.append('policy', this.sign.encodedPolicy)
      obsData.append('AWSAccessKeyId', this.sign.accessId)
      obsData.append('success_action_status', 200)
      obsData.append('signature', this.sign.postSignature)
      obsData.append('file', this.file.raw, this.file.name)
      uploadBySign(obsData, this.sign.host).then(response => {
        // 省略
      }).catch(() => {
        this.$message.error('保存失敗!')
      })
    }
發佈了56 篇原創文章 · 獲贊 11 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章