python - 亚马逊s3图片上传中PUT http请求403错误

标签 python amazon-web-services amazon-s3

我正在关注亚马逊 s3 图片上传教程 here 。一切看起来都很好。我的签名 url 响应返回 200 状态代码。但是,最后一个上传函数抛出 403 状态代码。

function upload_file(file, signed_request, url){
    var xhr = new XMLHttpRequest();
    xhr.open("PUT", signed_request);
    xhr.setRequestHeader('x-amz-acl', 'public-read');
    xhr.onload = function() {
        if (xhr.status === 200) {
            document.getElementById("preview").src = url;
            document.getElementById("avatar_url").value = url;
        }
    };
    xhr.onerror = function() {
        alert("Could not upload file.");
    };
    xhr.send(file);
}

这里的请求抛出错误

    xhr.open("PUT", signed_request);

我检查了我的网络,看到成功发送了 OPTIONS 类型的响应,并带有 200 状态代码。但是,具有相同 header 和属性的 PUT 类型的最后一个请求失败。

我的 key 在下面的 sign_s3 python 函数中表示

@app.route('/sign_s3/')
def sign_s3():
    AWS_ACCESS_KEY = 'MY_AWS_ACCESS_KEY'  # string
    AWS_SECRET_KEY = 'MY_AWS_SECRET_KEY' #string
    S3_BUCKET = 'MY_S3_BUCKET' # string
    object_name = urllib.quote_plus(request.args.get('file_name'))
    mime_type = request.args.get('file_type')

    expires = int(time.time()+60*60*24)
    amz_headers = "x-amz-acl:public-read"

    string_to_sign = "PUT\n\n%s\n%d\n%s\n%s\n%s" % (mime_type, expires, amz_headers, S3_BUCKET, object_name)
   print "%s" %string_to_sign
   signature = base64.encodestring(hmac.new(AWS_SECRET_KEY.encode(), string_to_sign.encode('utf8'), sha1).digest())
   signature = urllib.quote_plus(signature.strip())

   url = 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, object_name)

   content = json.dumps({
    'signed_request': '%s?AWSAccessKeyId=%s&Expires=%s&Signature=%s' % (url, AWS_ACCESS_KEY, expires, signature),
    'url': url,
    })
    return content

请问我哪里错了?我正在本地主机上运行我的 Flask 服务器,地址为 http://127.0.0.1:8080/ 。请问我哪里出错了?任何帮助将不胜感激。

最佳答案

再次注意格式:

StringToSign = HTTP-VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Expires + "\n" +
CanonicalizedAmzHeaders +
CanonicalizedResource; 

http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationQueryStringAuth

CanonicalizedResource 应该是...

/bucket/object_name

...但是你的代码...

string_to_sign = "PUT\n\n%s\n%d\n%s\n%s\n%s" % (mime_type, expires, amz_headers, S3_BUCKET, object_name)

...将创建这个:

bucket
object_name

...所以看起来您的格式字符串实际上需要...

"PUT\n\n%s\n%d\n%s\n/%s/%s"

关于python - 亚马逊s3图片上传中PUT http请求403错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34550173/

相关文章:

amazon-web-services - 用于 ECS 服务的没有 ELB 的替代服务发现

amazon-web-services - AWS s3 "public access"

amazon-s3 - 如何指定与目录不匹配的对象过期前缀?

amazon-web-services - 将 DMS 连接到 S3

Python - Tensorflow - LSTM- ValueError : Error when checking model target: expected dense_16 to have shape (None, 100) 但得到了形状为 (16, 2) 的数组

python - Twitter数据挖掘

python - 如何在 Python 3 中创建包?模块未找到错误

python - Python 和 Selenium 的授权异常

amazon-web-services - 使用 OAuth 放大 withAuthenticator v/s

amazon-s3 - Rails 5.2 Active Storage直接上传失败: CORS header ‘Access-Control-Allow-Origin’ missing