上传到Google Cloud Storage时获得403 SignatureDoesNotMatch?

scottc11

我正在尝试将客户端上的音频文件直接上传到我的Google Cloud Storage存储桶,目的是避免服务器端上传(文件大小受限制)。

我的问题:上传时出现403 SignatureDoesNotMatch错误。

这是响应中的错误:

<Error>
<Code>SignatureDoesNotMatch</Code>
<Message> The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method</Message>
<StringToSign>
PUT

audio/mp3
1511112552
/bucketname/pathtofile/019%20-%20top%20cntndr%20V1.mp3
</StringToSign>
</Error>

我已经创建了一个签名的URL。看起来像这样:

https://storage.googleapis.com/google-testbucket/testdata.txt?GoogleAccessId=
[email protected]&Expires=1331155464&Signature=BCl
z9e4UA2MRRDX62TPd8sNpUCxVsqUDG3YGPWvPcwN%2BmWBPqwgUYcOSszCPlgWREeF7oPGowkeKk
7J4WApzkzxERdOQmAdrvshKSzUHg8Jqp1lw9tbiJfE2ExdOOIoJVmGLoDeAGnfzCd4fTsWcLbal9
sFpqXsQI8IQi1493mw%3D

签名的网址是根据此处的Google文档中的指南构建的:https://cloud.google.com/storage/docs/access-control/create-signed-urls-program

但是,在文档中非常不清楚处理该签名url的客户端javascript部分。

这是我的python代码,用于创建并返回已签名的url。

GOOGLE_SERVICE_CREDENTIALS = 'google-service-credentials.json'

def get_signed_url(request):
    filename = request.GET.get('filename')
    expiration = request.GET.get('expiration')
    type = request.GET.get('type')
    signed_url = CloudStorageSignedURL(
                method='PUT',
                file_name=filename,
                expiration_m=expiration,
                content_type=type
                )
    signed_url = signed_url.sign_url()


    return JsonResponse({ 'signed_url': signed_url })






class CloudStorageSignedURL(object):


    def __init__(self, method, file_name, expiration_m, content_type):
        self.HTTP_method = method
        self.content_type = 'content-type: ' + content_type
        self.expiration = int(expiration_m)
        self.file_name = file_name


    def sign_url(self):


        expiration_dt = datetime.utcnow() + timedelta(minutes=self.expiration)
        expiration = int(time.mktime( expiration_dt.timetuple() ))
        bucket_path = '/' + settings.CLOUD_STORAGE_BUCKET + '/dev/tests/' + self.file_name
        signature_string = self.HTTP_method + '\n' + '\n' + self.content_type + "\n" + str(expiration) + '\n' + bucket_path
        print(signature_string)
        creds = ServiceAccountCredentials.from_json_keyfile_name(GOOGLE_SERVICE_CREDENTIALS)
        client_email = creds.service_account_email
        signature = creds.sign_blob(signature_string)[1]
        encoded_signature = base64.urlsafe_b64encode(signature).decode('utf-8')
        base_url = settings.CLOUD_STORAGE_ROOT + 'dev/tests/' + self.file_name


        return base_url + '?GoogleAccessId=' + client_email + '&Expires=' + str(expiration) + '&Signature=' + encoded_signature

客户端Javascript上传文件

import $ from 'jquery';
import axios from 'axios';



$("document").ready( () => {
  console.log('window loaded');


  $("#id_audio_file").change(function() {

    const file = this.files[0]

    const url = window.location.href.replace('submit/', 'upload/');
    $.get(url + `?filename=${file.name}&expiration=10&type=${file.type}`, (data) => {
      upload(data.signed_url, file);
    })

  });
});



function upload(url, file) {

  const config = {
    headers: {
      'Content-Type': file.type,
    }
  }

  axios.put(url, file, config)
    .then(function (res) {
      console.log(res);
    })
    .catch(function (err) {
      console.log(err);
    });
}

我真的觉得我已经涵盖了这里的所有基础,但是显然我错过了几分钟。任何帮助将不胜感激!

图多尔米

首先,请确保您正在使用的服务帐户具有将文件上传到存储桶的适当权限:通过IAM设置或通过访问控制

如果设置了该值,则取决于代码。我已经尝试过使用您的方法,而不是手动创建签名的url ,它也对我同样失败,并出现相同的错误。但是,我已经使用Google Cloud python客户端库中generate_signed_url方法设法通过一个signedURL上传了文件少说话,多代码:

from google.oauth2 import service_account
import base64
import json
from datetime import datetime, timedelta
import time
import requests
from google.cloud import storage

# client = storage.Client()
# bucket = client.get_bucket('a-test-bucket')
# blob = bucket.blob('/test/mpthreetest.mp3')

GOOGLE_SERVICE_CREDENTIALS = 'signed_url_account.json'
FILENAME = 'mpthreetest.mp3'
EXPIRATION = 1511826970  # epoch time
TYPE = 'audio/mp3'

creds = service_account.Credentials.from_service_account_file(GOOGLE_SERVICE_CREDENTIALS)
bucket = storage.Client().get_bucket('a-test-bucket')
blob = bucket.blob('test/mpthreetest.mp3')

signed_url = blob.generate_signed_url(method='PUT', expiration=EXPIRATION, content_type=TYPE, credentials=creds)

print (signed_url)

req = requests.put(signed_url, open(FILENAME), headers={'Content-Type': TYPE})
print(req.content)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将 xml 文件上传到 Google Cloud Storage 时出错

将 Excel 上传到 Google Cloud Storage 时出错

将图像从Google Cloud Function上传到Cloud Storage

仅 14 个字节上传到 Google Cloud Storage

使用Flask将文件上传到Google Cloud Storage

Alamofire无法将文件上传到Google Cloud Storage

将文件上传到Google Cloud Storage:500后端错误

自动将数据上传到 Google Cloud Storage 和 BigQuery

将.raw文件上传到Google Cloud Storage

使用 Codeigniter 将文件上传到 Google Cloud Storage

使用 For 循环将多个文件上传到 Google Cloud Storage

使用PostMan时,Google Cloud签名的网址为“ SignatureDoesNotMatch”,但可以在Python上正常使用

上传失败,状态代码:403 SignatureDoesNotMatch 当 multiPartUpload 为 true 时

在node.js中将文件上传到Google Cloud Storage时出错

使用“gsutil”从 Cloud Storage 存储分区上传到 Google Colab 时出错

使用Google App Engine(Python)将文件上传到Google Cloud Storage

使用Google App Engine将大文件上传到Google Cloud Storage

尝试使用Superbalist / flysystem-google-cloud-storage上传到Google云存储

将文件上传到Google Cloud Storage而不在本地下载文件?

Jclouds分段上传到Google Cloud Storage失败,出现400错误请求

使用JSON API将文件上传到Google Cloud Storage,错误401未经授权

如何使用Curl和API密钥上传到Google Cloud Storage?

将文件直接上传到Google Cloud Storage for GAE应用

如何在Python 3上将文件上传到Google Cloud Storage?

使用PHP和Ajax将文件上传到Google Cloud Storage Bucket

将Python文件上传到Google Cloud Storage Bucket返回管道中断错误

使用Node JS将图像从本地目录上传到Google Cloud Storage

如何从Node中的图像URL将图像上传到Google Cloud Storage?

使用 GAE 和 Google Cloud Storage 从 csv 文件上传到存储桶图片