Колба Python AWS S3 ЕС Центральный |Неверный запрос Предоставленный вами механизм авторизации не поддерживается.Пожалуйста, используйте AWS4-HMAC-SHA256 - PullRequest
0 голосов
/ 24 мая 2018

Прежде всего, я знаю, что есть много похожих тем, я перекрасил их все и документ S3 (пожалуйста, не закрывайте эту ветку).Исправление везде одинаковое:

Просто измените 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.Я тестирую все на локальном хосте, и по умолчанию для use_ssl установлено значение true.

Я пытался загрузить эту версию на действующий сайт (там включен SSL).Не сработало, все та же ошибка.

Я также пытался использовать use_ssl = False на localhost, все та же ошибка.

1 Ответ

0 голосов
/ 24 мая 2018

Проблема была в HTML и как я назвал поля ввода.Я взял пример из более старого учебного пособия, но вы должны создать свою форму так, как это объясняется здесь 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})

Я посмотрел на сгенерированный ответ вна консоли разработчика у меня были следующие значения:

enter image description here

Я использовал здесь HTML-форму, все поля ввода, которые не закомментированы, не были использованымной.Я просто включаю их, поскольку amazon показывает их все в их примере:

<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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...