I get problem for disable csrf using flask-wtf for a restapi. The problem is similar like here: Flask-Restful POST fails due CSRF protection of Flask-WTF, but I use flask original instead of flask-restful.
I use the @csrf.exempt
decorator, and I did exactly like the documentation, but still can not disable the csrf. Here is my code, do you know what is the problem?
myApp.py
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField
from flask_wtf.csrf import CSRFProtect
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
app.config['SECRET_KEY'] = "secret"
db = SQLAlchemy(app)
csrf = CSRFProtect(app) # initialize the csrf protect
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String())
class myForm(FlaskForm):
username = StringField("user name")
@app.route("/check", methods=['POST'])
@csrf.exempt # why this code doesn't work???!!! :(
def check():
form = myForm(request.form)
if form.validate():
user = User(username=form.username.data)
db.session.add(user)
db.session.commit()
return jsonify(message="user saved!"), 200
else:
return jsonify(message=form.errors), 404
if __name__ == '__main__':
app.run(debug=True)
My Postman always return:
{
"message": {
"csrf_token": [
"The CSRF token is missing."
]
}
}
You can disable CSRF protection in all views by default, by setting WTF_CSRF_CHECK_DEFAULT to False , and selectively call protect() only when you need. This also enables you to do some pre-processing on the requests before checking for the CSRF token.
CSRF Token WorkflowIf the credentials are correct, the server generates a session and CSRF token. The request is sent back to the client, and the session is stored in a cookie while the token is rendered in a hidden form field. The client includes the session cookie and the CSRF token with the form submission.
Flask Forms. FlaskForm Class. Flask provides an alternative to web forms by creating a form class in the application, implementing the fields in the template and handling the data back in the application.
FlaskForm.validate()
seems to be the one returning that error, i.e. try
form = myForm(request.form, csrf_enabled=False)
or
class myForm(FlaskForm):
class Meta:
csrf = False
username = StringField("user name")
since csrf_enabled
seems to be deprecated.
From the documentation
Any view using FlaskForm to process the request is already getting CSRF protection.
You can pass meta={'csrf': False} as parameter in your constructor
form = myForm(request.form, meta={'csrf': False})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With