I am trying to send a post request to a Flask server that uses flask_jwt_extended tokens. I don’t want the page to refresh after each submit and I managed to do this using jquery. But I am unable to send CSRF token in a way that flask_jwt_extended can authenticate user.
function myfunction(action, id, csrf_token){
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:5000/accept", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
action: action,
id: id,
csrf_token: csrf_token
}));
}
$(document).ready(function() {
$(document).on('click', '#my-form', function(event) {
var action = $(event.target).attr('value');
var f = $(this);
csrf_token = f.find('input[id=csrf_token]');
myfunction(action, f.find('[name=song_id]').val(), csrf_token)
return false;
});
});
@app.route('/accept', methods=["POST"])
@jwt_required
def accept():
user = get_jwt_identity()
...
When I try the following I get a 401 error, which is not surprising as I am not passing the csrf token as in a form. If I simply submit a post request on the form, it works fine.
EDIT: On my backend I am using the following setting for flask_jwt_extended:
app.secret_key = 'loginner'
app.config['JWT_SECRET_KEY'] = 'super-secret'
app.config['JWT_TOKEN_LOCATION'] = ['cookies', 'headers']
app.config['JWT_BLACKLIST_ENABLED'] = True
app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access', 'refresh']
app.config['JWT_COOKIE_CSRF_PROTECT'] = False # the bearer request works when this is False, but ideally it would be True
app.config['JWT_CSRF_CHECK_FORM'] = True
And I am getting the identify in the following:
@app.route('/accept', methods=["POST"])
@jwt_required
def accept():
user = get_jwt_identity()
...
It works as expected when app.config['JWT_COOKIE_CSRF_PROTECT'] = False