简体   繁体   中英

ClientError (SignatureDoesNotMatch) when trying to upload file to Amazon S3 from an EC2 instance in a Flask app

I'm trying to write a Flask app to upload to an AWS S3 bucket. Where, when I run this locally in PyCharm it works fine. However, once I deployed it to AWS (deploying the Flask app on port 80) I now get an error...

botocore.exceptions.ClientError: An error occurred (SignatureDoesNotMatch) when calling the ListBuckets operation: The request sture we calculated does not match the signature you provided. Check your key and signing method.

When the keys work locally...but don't work on the AWS EC2 instance. Some of my initial thoughts were maybe a port issue or an issue with boto3. Though I'm not sure because it works locally, just not on AWS.

Any help? Here is my code...with keys and URLs removed ofc

app.py

from flask import Flask, render_template, flash
from werkzeug.utils import secure_filename
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileRequired
from tools import s3_upload

'''
Author: xxx
'''

app = Flask(__name__)
app.config.from_object('config')
# Flask Secret Key
app.secret_key = 'xxxxx'

# Limits what file types can be uploaded
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']

# Initializes upload form
class UploadForm(FlaskForm):
    example = FileField(validators=[FileRequired()])

# Route for root, handles on click action for upload form
@app.route('/', methods=['POST', 'GET'])
def upload_page():
    form = UploadForm()
    if form.validate_on_submit():
        file = form.example.data
        filename = secure_filename(file.filename)
        output = s3_upload(file,filename)
        flash('{src} uploaded to S3'.format(src=form.example.data.filename))
    return render_template('index.html', form=form)

if __name__ == '__main__':
    app.run()

tools.py

import boto3
from flask import current_app as app

'''
Author: xxx
'''

def s3_upload(source_file, source_filename):
    # What directory on Amazon S3 Bucket to upload to.
    upload_dir = app.config["S3_UPLOAD_DIRECTORY"]

    #Connect to S3 and upload file
    s3 = boto3.client('s3')
    s3.upload_fileobj(source_file, app.config["S3_BUCKET"], upload_dir + "/" + source_filename)

config.py

S3_KEY = 'xxx'
S3_SECRET = 'xxxx'
S3_UPLOAD_DIRECTORY = 'xxxx'
S3_BUCKET = 'xxxx'
ALLOWED_EXTENSIONS = ['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']

SECRET_KEY = "xxxx"
DEBUG = True

尝试将客户端对象更改为:

client = boto3.client('s3', config=boto3.session.Config(signature_version='s3v4'))

事实证明,该问题是AWS的关键问题,也是我使用此处在网络上被阻止的端口引起的网络安全问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM