aliyun / alibabacloud-oss-go-sdk-v2

Alibaba Cloud OSS SDK for Go v2
Apache License 2.0
20 stars 1 forks source link

签名 url 上传文件报错 SignatureDoesNotMatch #25

Closed jiaopengzi closed 2 months ago

jiaopengzi commented 2 months ago

官方大佬您好:

使用 golang 参考官方文档生成签名url.

package main

import (
    "context"
    "fmt"
    "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
    "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
    "time"
)

func main() {
    // 账号密码已脱敏
    provider := credentials.NewStaticCredentialsProvider("LTAI5t8E6b****************", "zoubq1qF1vuy****************")
    cfg := oss.LoadDefaultConfig().
        WithCredentialsProvider(provider).
        WithRegion("cn-chengdu").WithEndpoint("oss-cn-chengdu.aliyuncs.com")

    client := oss.NewClient(cfg)

    result, err := client.Presign(context.TODO(), &oss.PutObjectRequest{
        Bucket:   oss.Ptr("jiaopengzi-image"),
        Key:      oss.Ptr("blog/uploads/6.png"),
        Metadata: map[string]string{"user": "jack"},
    },
        oss.PresignExpires(10*time.Minute),
    )

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Printf("Sign Method:%v\n", result.Method)
    fmt.Printf("Sign Url:%v\n", result.URL)
    fmt.Printf("Sign Expiration:%v\n", result.Expiration)
    for k, v := range result.SignedHeaders {
        fmt.Printf("SignedHeader %v:%v\n", k, v)
    }
    // 控台输出结果如下:
    // Sign Method:PUT
    // Sign Url:https://jiaopengzi-image.oss-cn-chengdu.aliyuncs.com/blog/uploads/6.png?x-oss-credential=LTAI5t8E6bUfAieYzkiYQKtH%2F20240807%2Fcn-chengdu%2Foss%2Faliyun_v4_request&x-oss-date=20240807T093054Z&x-oss-expires=600&x-oss-signature=5503e04ce95bd0d221fb6d165f77e30f620d1585055f2054f5dae0ebd05bdc46&x-oss-signature-version=OSS4-HMAC-SHA256
    // Sign Expiration:2024-08-07 17:40:54.5249974 +0800 CST m=+600.001644301
    // SignedHeader X-Oss-Meta-User:jack

}

上传文件

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>File Upload</title>
  </head>
  <body>
    <div>
      <input type="file" id="fileInput" />
      <button id="uploadButton">Upload</button>
    </div>

    <script>
      var fileInput = document.getElementById('fileInput')
      var uploadButton = document.getElementById('uploadButton')

      var file = null

      fileInput.addEventListener('change', function (e) {
        file = e.target.files[0]
      })

      uploadButton.addEventListener('click', function () {
        if (!file) {
          console.error('No file selected')
          return
        }

        var signedUrl =
          'https://jiaopengzi-image.oss-cn-chengdu.aliyuncs.com/blog/uploads/6.png?x-oss-credential=LTAI5t8E6bUfAieYzkiYQKtH%2F20240807%2Fcn-chengdu%2Foss%2Faliyun_v4_request&x-oss-date=20240807T093054Z&x-oss-expires=600&x-oss-signature=5503e04ce95bd0d221fb6d165f77e30f620d1585055f2054f5dae0ebd05bdc46&x-oss-signature-version=OSS4-HMAC-SHA256' // 签名URL
        var formData = new FormData()
        formData.append('file', file)

        fetch(signedUrl, {
          method: 'PUT',
          body: formData,
          headers: {
            'Content-Type': 'multipart/form-data',
            'x-oss-meta-user': 'jack',
          },
        })
          .then((response) => response.json())
          .then((data) => console.log(data))
          .catch((error) => console.error(error))
      })
    </script>
  </body>
</html>

在不使用签名url是可以上传文件的,账号验证应该是没有问题的

但是使用了签名url上传文件报错SignatureDoesNotMatch如下,请给予一些帮助,非常感谢!

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>SignatureDoesNotMatch</Code>
  <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
  <RequestId>66B33F1BF299AF35301DD83C</RequestId>
  <HostId>jiaopengzi-image.oss-cn-chengdu.aliyuncs.com</HostId>
  <CanonicalRequest>PUT
/jiaopengzi-image/blog/uploads/6.png
x-oss-credential=LTAI5t8E6bUfAieYzkiYQKtH%2F20240807%2Fcn-chengdu%2Foss%2Faliyun_v4_request&amp;x-oss-date=20240807T093054Z&amp;x-oss-expires=600&amp;x-oss-signature-version=OSS4-HMAC-SHA256
content-type:multipart/form-data
x-oss-meta-user:jack

UNSIGNED-PAYLOAD</CanonicalRequest>
  <CanonicalRequestBytes>50 55 54 0A 2F 6A 69 61 6F 70 65 6E 67 7A 69 2D 69 6D 61 67 65 2F 62 6C 6F 67 2F 75 70 6C 6F 61 64 73 2F 36 2E 70 6E 67 0A 78 2D 6F 73 73 2D 63 72 65 64 65 6E 74 69 61 6C 3D 4C 54 41 49 35 74 38 45 36 62 55 66 41 69 65 59 7A 6B 69 59 51 4B 74 48 25 32 46 32 30 32 34 30 38 30 37 25 32 46 63 6E 2D 63 68 65 6E 67 64 75 25 32 46 6F 73 73 25 32 46 61 6C 69 79 75 6E 5F 76 34 5F 72 65 71 75 65 73 74 26 78 2D 6F 73 73 2D 64 61 74 65 3D 32 30 32 34 30 38 30 37 54 30 39 33 30 35 34 5A 26 78 2D 6F 73 73 2D 65 78 70 69 72 65 73 3D 36 30 30 26 78 2D 6F 73 73 2D 73 69 67 6E 61 74 75 72 65 2D 76 65 72 73 69 6F 6E 3D 4F 53 53 34 2D 48 4D 41 43 2D 53 48 41 32 35 36 0A 63 6F 6E 74 65 6E 74 2D 74 79 70 65 3A 6D 75 6C 74 69 70 61 72 74 2F 66 6F 72 6D 2D 64 61 74 61 0A 78 2D 6F 73 73 2D 6D 65 74 61 2D 75 73 65 72 3A 6A 61 63 6B 0A 0A 0A 55 4E 53 49 47 4E 45 44 2D 50 41 59 4C 4F 41 44 </CanonicalRequestBytes>
  <OSSAccessKeyId>LTAI5t8E6bUfAieYzkiYQKtH</OSSAccessKeyId>
  <SignatureProvided>5503e04ce95bd0d221fb6d165f77e30f620d1585055f2054f5dae0ebd05bdc46</SignatureProvided>
  <StringToSign>OSS4-HMAC-SHA256
20240807T093054Z
20240807/cn-chengdu/oss/aliyun_v4_request
47f4949e7f7123df9e314b3e059ac1e7d46c04f99739b5db5d5bd429702bed81</StringToSign>
  <StringToSignBytes>4F 53 53 34 2D 48 4D 41 43 2D 53 48 41 32 35 36 0A 32 30 32 34 30 38 30 37 54 30 39 33 30 35 34 5A 0A 32 30 32 34 30 38 30 37 2F 63 6E 2D 63 68 65 6E 67 64 75 2F 6F 73 73 2F 61 6C 69 79 75 6E 5F 76 34 5F 72 65 71 75 65 73 74 0A 34 37 66 34 39 34 39 65 37 66 37 31 32 33 64 66 39 65 33 31 34 62 33 65 30 35 39 61 63 31 65 37 64 34 36 63 30 34 66 39 39 37 33 39 62 35 64 62 35 64 35 62 64 34 32 39 37 30 32 62 65 64 38 31 </StringToSignBytes>
  <EC>0002-00000201</EC>
  <RecommendDoc>https://api.aliyun.com/troubleshoot?q=0002-00000201</RecommendDoc>
</Error>

使用 signedUrl上传文件的时候,已经将 Bucket 的跨域都设置为了*

image-20240807173904449

用户读写权限

image-20240807174027500

账号权限

image-20240807174346007

huiguangjun commented 2 months ago
  1. Content-Type 是参与签名的, Presign 参数里, 没有包含 content-type header
  2. fetch(signedUrl, { method: 'PUT', body: formData, headers: { 'Content-Type': 'multipart/form-data', 设置了content-type,

所以出现签名错误.

jiaopengzi commented 2 months ago

感谢指导,修改上传方式和 签名的时候ContentType: oss.Ptr("image/png") 和 发送请求'Content-Type': 'image/png'对齐就成功了.

    result, err := client.Presign(context.TODO(), &oss.PutObjectRequest{
        Bucket:      oss.Ptr("jiaopengzi-image"),
        Key:         oss.Ptr("blog/uploads/6.png"),
        ContentType: oss.Ptr("image/png"),
        Metadata:    map[string]string{"user": "jack"},
    }
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>File Upload</title>
  </head>
  <body>
    <div>
      <input type="file" id="fileInput" />
      <button id="uploadButton">Upload</button>
    </div>

    <script>
      var fileInput = document.getElementById('fileInput')
      var uploadButton = document.getElementById('uploadButton')

      var file = null

      fileInput.addEventListener('change', function (e) {
        file = e.target.files[0]
      })

      uploadButton.addEventListener('click', function () {
        if (!file) {
          console.error('No file selected')
          return
        }

        var signedUrl =
          'https://jiaopengzi-image.oss-cn-chengdu.aliyuncs.com/blog/uploads/6.png?x-oss-credential=LTAI5tERcFBucGpvadG8jktr%2F20240807%2Fcn-chengdu%2Foss%2Faliyun_v4_request&x-oss-date=20240807T121329Z&x-oss-expires=600&x-oss-signature=06d9a3434b94186949ed50f1d9f3a95b938f781e1aa665bbb2aebe1bb320ddbb&x-oss-signature-version=OSS4-HMAC-SHA256' // 签名URL

        var reader = new FileReader()
        reader.readAsArrayBuffer(file)
        reader.onload = function (event) {
          var arrayBuffer = reader.result

          fetch(signedUrl, {
            method: 'PUT',
            body: arrayBuffer,
            headers: {
              'Content-Type': 'image/png',
              'x-oss-meta-user': 'jack1',
            },
          })
            .then((response) => response.json())
            .then((data) => console.log(data))
            .catch((error) => console.error(error))
        }
      })
    </script>
  </body>
</html>