对象存储

使用预签名URL直传对象存储

2024-09-05 06:18:15

实践背景

对象存储SDK提供的预签名接口可以生成预签名URL,通过预签名URL,移动端APP可以直接上传或者下载文件。不需要使用SDK和密钥,使用HTTP接口就可以进行文件的上传和下载。

应用流程

使用预签名URL直传对象存储应用流程如下:

操作步骤

生成预签名URL

业务服务器配置长期密钥,调用预签名接口生成预签名URL,具体可参考如下Golang示例:

  • 上传预签名

func GeneratePresignedUploadUrl(svc *s3.S3) {
               bucket := "example-bucket"
               key := "example-key"
               // 链接过期时间
               expire := 5 * time.Minute
               req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
                               Bucket: aws.String(bucket),
                               Key:    aws.String(key),
               })
               urlStr, err := req.Presign(expire)
               if err != nil {
                               fmt.Printf("Unable to sign request, %v", err)
               } else {
                               fmt.Printf("Presigned URL: %v", urlStr)
               }
}
  • 下载预签名

// 生成预签名下载链接
func GeneratePresignedDownloadUrl(svc *s3.S3) {
               bucket := "example-bucket"
               key := "example-key"
               // 链接过期时间
               expire := 5 * time.Minute
               req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
                               Bucket: aws.String(bucket),
                               Key:    aws.String(key),
               })
               urlStr, err := req.Presign(expire)
               if err != nil {
                               fmt.Printf("Unable to sign request, %v", err)
               } else {
                               fmt.Printf("Presigned URL: %v", urlStr)
               }
}

使用预签名URL直传

移动端通过业务服务器获取到预签名URL,使用HTTP接口和预签名URL上传或者下载文件。具体可参照如下Goalng示例:

  • 上传

// 使用HTTP接口和预签名URL上传
func UsePresignedUploadUrl(url string) {
               filepath := "YOUR_FILE_PATH"
               file, err := os.Open(filepath)
               if err != nil {
                               fmt.Printf("Unable to open file:%v", err)
                               os.Exit(1)
               }
               defer file.Close()
 
               request, _ := http.NewRequest("PUT", url, file)
               request.Header.Add("Content-Type", "YOUR_CONTENT_TYPE")
               res, err := http.DefaultClient.Do(request)
               if err != nil {
                               fmt.Printf("err(%v)", err)
                               return
               }
               defer res.Body.Close()
               body, _ := ioutil.ReadAll(res.Body)
 
               fmt.Println(res)
               fmt.Println(string(body))
}
  • 下载

// 使用HTTP接口和预签名URL下载
func UsePresignedDownloadUrl(url string) {
               client := &http.Client{}
               req, err := http.NewRequest("GET", url, nil)
               if err != nil {
                               panic(err)
               }
               resp, err := client.Do(req)
               if err != nil {
                               panic(err)
               }
               defer resp.Body.Close()
               file, err := os.Create("YOUR_FILE_NAME")
               if err != nil {
                               panic(err)
               }
               defer file.Close()
               _, err = io.Copy(file, resp.Body)
               if err != nil {
                               panic(err)
               }
               println("Download success")
}


DTBvq07XGF6s