I've been pulling my hair out on this error message. Please bear with me as I am just not that smart. I have a flask application being made in python with CSRFProtect enabled across the application.
Web Service in python
'''Using flask to create the python ws'''
from flask import Flask, request, session
from flask_cors import CORS
from flask_wtf.csrf import CSRFProtect
from dotenv import dotenv_values
from Validator import geia_std_xsd_validation
# returns a dict of the values contained within the .env file
config = dotenv_values('.env')
ALLOWED_EXTENSIONS = {'xml'}
APP = Flask(__name__)
SECRET_KEY = 'test12'
csrf = CSRFProtect()
origin_array = config['WHITELIST_ARRAY']
cors = CORS(APP, origins=origin_array, expose_headers=['Content-Type', 'X-CSRFToken'], supports_credentials=True)
csrf.init_app(APP)
APP.config['SECRET_KEY'] = SECRET_KEY
APP.vars = {}
def allowed_file(filename):
"""
Checks to make sure the uploaded file is in the list of allowed extensions.
"""
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
# Do we need this?
@APP.route('/', methods = ['GET'])
def server_up():
'''This method handles the calls to our ws'''
if request.method == 'GET':
return {
"message": APP.config.get('WTF_CSRF_FIELD_NAME'),
'sesh': session
}
@APP.before_request
def test():
session['csrf_token'] = 'test12'
print('before')
@APP.route('/xsd_validator', methods = ['POST'])
# @csrf.exempt # we'll figure this out later...
def xsd_validation():
'''This method handles the calls to our ws'''
if request.method == 'POST':
print('HITTING')
# If there isn't a file in the request.
if len(request.files) <= 0:
print('No files in response')
return 'No file sent'
# # Set the file from the request.
file = request.files['testFile']
# # Make sure we have a filename so we can check extension.
if file.filename == '':
print('Blank filename')
return 'Invalid filename'
# # If there is a file and we allow that file type then validate it against the schema.
if file and allowed_file(file.filename):
print('Got into the file statement')
file_text = file.read()
errors = geia_std_xsd_validation(file_text)
return errors
return 'Nothing Happened'
if __name__ == "__main__":
// APP.run(//the sauce)
I have another web service made in expressjs that will hit this web service with a file for xml validation with this function
const testTHATSHIZZLE = async (req, res) => {
const csrf = 'test12'
const file = req.files.testFile
const name = file.name
// not recognizing blob D:
const submittedFile = new FormData()
const arrayBuffer = Uint8Array.from(file.data).buffer
const nodeBuffer = Buffer.from(arrayBuffer)
// const fileBlob = new Blob([file.data])
submittedFile.append('testFile', nodeBuffer, name)
await axios.post('https://localhost:6030/xsd_validator', submittedFile, {
csrf_token: csrf,
withCredentials: true,
headers: {
'X-CSRFToken': csrf,
'Content-Type': 'multipart/form-data'
}
}).then(response => {
res.send(response.data)
}).catch(error => {
console.log(error)
res.send(error)
})
}
Just for baseline, this totally works when csrf.exempt is uncommented out above the route I need this to take.
But when csrf is enabled for the route, I am getting the bad request 400 error CSRF session token missing.
I am looking all over and I just can't figure this out. When I put the flask app in debugger and try to see what session variables there are it is an empty ImmutableDict. As you can see I am setting the csrf tester token under the header, adding withCredentials to the axios call. The flask app has cors enabled and supports credentials.
I am so at a loss as to how axios and my flask app are interacting. I am able to set session variables in the before_request method for the GET route, but it fails before I can hit the POST route. Not that I thought I SHOULD be doing that. I just wanted to test.
There's no other variables in session?
I don't know if I'm invoking this wrong or not, but I am hoping someone knows more about hitting a flask app with csrf protections from an external web service not using flask forms.
I've tried going through the gitlab repo for flask-wtf and looking right at csrf.py, but that just tells me this should be working already. I don't know why a session isn't established when I make an axios call.