首先我知道有许多类似的线程,我全部都是红色和S3 Docu(请不要关闭这个帖子)。修复无处不在:
只需将sugnature_version
更改为v4
,因为eu central
是在2014年之后创建的,不再支持v2
。
我现在尝试了所有语法,但我仍然遇到错误。
session = boto3.Session(
aws_access_key_id=app.config['MY_AWS_ID'],
aws_secret_access_key=app.config['MY_AWS_SECRET'],
region_name='eu-central-1'
)
s3 = session.client('s3', config=Config(signature_version='s3v4'))
presigned_post = s3.generate_presigned_post(
Bucket = 'mybucket',
Key = 'videos/' + file_name,
Fields = {"acl": "public-read", "Content-Type": file_type},
Conditions = [
{"acl": "public-read"},
{"Content-Type": file_type}
],
ExpiresIn = 3600
)
我试过到处改变它。我还将我的boto3
安装降级为版本1.6.6
和1.4.4
,但也没有用。我将它恢复到最新版本,即boto3==1.7.26
错误:
InvalidRequest
The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.
每个帖子都建议使用相同的修复程序,可能它不起作用,因为我使用Python / Flask
。有什么必须以不同的方式完成吗?
我正在尝试通过客户端将巨大的视频文件直接上传到S3,因此我需要签署请求。
修改
我想可能存在SSL问题。我正在测试localhost上的所有内容,use_ssl
的默认选项是true
。
我尝试将此版本上传到实际网站(启用了SSL)。没有用,仍然是同样的错误。
我还尝试在use_ssl = False
上使用localhost
,仍然是同样的错误。
答案 0 :(得分:0)
问题在于HTML以及我如何命名输入字段。我从一个较旧的教程中提取了一个示例,但您必须按照解释的方式构建表单here by amazon
我已经使用了他们提供的所有输入。我已经检查了我的响应,该响应是由我的sign_s3函数生成的,并且已经填充了表单中的所有相应字段。
这是我的签名功能:
# Sign request for direct file upload through client for video
@app.route('/sign_s3/<path:file_name_data>/<path:file_type_data>/<up_type>', methods=["GET", "POST"])
@login_required
@check_confirmed
def sign_s3(file_name_data, file_type_data, up_type):
if "localhost" in request.url_root:
if up_type == "profile_vid":
file_name = str(current_user.id) + get_random_code(5) + "local-profil-video." + file_name_data.split(".")[-1]
else:
file_name = str(current_user.id) + str(randint(1,100)) + "local-post-video-temp." + file_name_data.split(".")[-1]
else:
if up_type == "profile_vid":
file_name = str(current_user.id) + get_random_code(5) + "-profil-video." + file_name_data.split(".")[-1]
else:
file_name = str(current_user.id) + str(randint(1,100)) + "-post-video-temp." + file_name_data.split(".")[-1]
file_type = file_type_data
session = boto3.Session(
aws_access_key_id=app.config['MY_AWS_ID'],
aws_secret_access_key=app.config['MY_AWS_SECRET'],
region_name='eu-central-1'
)
s3 = session.client('s3', config=Config(signature_version='s3v4'))
presigned_post = s3.generate_presigned_post(
Bucket = 'mybucket',
Key = 'videos/' + file_name,
Fields = {"acl": "public-read", "Content-Type": file_type},
Conditions = [
{"acl": "public-read"},
{"Content-Type": file_type}
],
ExpiresIn = 3600
)
if up_type == "profile_vid":
if current_user.profile_video != None:
delete_file_from_aws("videos/", current_user.profile_video)
setattr(current_user, "profile_video", file_name)
else:
print ('post video has been uploaded, no need to delete or set here')
db_session.commit()
return json.dumps({'data': presigned_post, 'url': 'https://s3.eu-central-1.amazonaws.com/mybucket/' + 'videos/' + file_name, 'created_file_name' : file_name})
我查看了开发控制台中生成的响应,我有这些值:
我使用的HTML表单在这里,我没有使用所有未注释的输入字段。我只是将它们包括在内,因为亚马逊在他们的例子中展示了所有这些:
<form id="direct_s3_profile_video_form" class="form-horizontal" role="form" method="POST" enctype="multipart/form-data">
<!-- Content-Type: -->
<input type="hidden" name="Content-Type">
<!-- <input type="hidden" name="x-amz-meta-uuid"> -->
<!-- <input type="hidden" name="x-amz-server-side-encryption"> -->
<input type="hidden" name="X-Amz-Credential">
<input type="hidden" name="X-Amz-Algorithm">
<input type="hidden" name="X-Amz-Date">
<!-- Tags for File: -->
<!-- <input type="hidden" name="x-amz-meta-tag"> -->
<input type="hidden" name="Policy">
<input type="hidden" name="X-Amz-Signature">
<input id="NEW_fileupload_video" type="file" name="file" accept="video/*">
<button type="submit"> Upload </button>
</form>
另请注意,文件输入必须位于底部,因为:
之后的元素将被忽略
在我的例子中,表单的值是动态创建的,所以我使用JS填充表单:
$('#direct_s3_profile_video_form').find('input[name="key"]').val(response_json_data.data.fields['key']);
$('#direct_s3_profile_video_form').find('input[name="acl"]').val(response_json_data.data.fields['acl']);
$('#direct_s3_profile_video_form').find('input[name="Content-Type"]').val(response_json_data.data.fields['Content-Type']);
$('#direct_s3_profile_video_form').find('input[name="X-Amz-Credential"]').val(response_json_data.data.fields['x-amz-credential']);
$('#direct_s3_profile_video_form').find('input[name="X-Amz-Algorithm"]').val(response_json_data.data.fields['x-amz-algorithm']);
$('#direct_s3_profile_video_form').find('input[name="X-Amz-Date"]').val(response_json_data.data.fields['x-amz-date']);
$('#direct_s3_profile_video_form').find('input[name="Policy"]').val(response_json_data.data.fields['policy']);
$('#direct_s3_profile_video_form').find('input[name="X-Amz-Signature"]').val(response_json_data.data.fields['x-amz-signature']);
$('#direct_s3_profile_video_form').attr('action', 'https://mybucket.s3.amazonaws.com');