Francisco
Francisco

Reputation: 561

flask error CSRF token is missing

I'm trying to disable some requests by the post method with the extension flask-retful, in the documentation it tells me how to disable csrt but it does not work, these are my files

/app.py

from flask import Flask
from models.model import db
from Views.View import view
from api import restApi
from api import _csrfProtect

application = Flask(__name__)
application.config.from_object('config.developement')
#application.register_blueprint(view)
restApi.init_app(application)
_csrfProtect.init_app(application)
db.init_app(application)

/config/configuration.py

class developement(object):
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = 'mysql:........'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    #SECRET_KEY = 'misecret'
    WTF_CSRF_SECRET_KEY='secretKey'
    #WTF_CSRF_CHECK_DEFAULT=False
    WTF_CSRF_ENABLED = True

/forms/forms.py

from flask_wtf import FlaskForm,Form
from wtforms import StringField

class NewUser(FlaskForm):
    name = StringField('name')
    surname = StringField('surname')
    email = StringField('email')
    class Meta:
        csrf=False

/api/api.py

from flask import jsonify,request
from .csrfProtect import _csrfProtect
from sqlalchemy.exc import IntegrityError
from models.model import db,Student
from forms import NewUser
from flask_restful import Resource,Api

restApi = Api()

class AddUser(Resource):
    method_decorators = [_csrfProtect.exempt]
    def post(self):
        form = NewUser(request.POST)
        if form.validate():
            return jsonify(data='success')
        else:
            return jsonify(error=form.errors)

restApi.add_resource(AddDataUser,'/updatedata')
restApi.add_resource(AddUser,'/newuser')

/api/csrfProtect.py

from flask_wtf import CSRFProtect
_csrfProtect = CSRFProtect()

all requests are the same

{
    "message": "The CSRF token is missing."
}

and use to deactivate the csrf

class Meta:
    csrf=False

and

method_decorators = [_csrfProtect.exempt]

According to all the documentation that I have found, I have tried everything he says but without any result, csrf is always active.

Upvotes: 3

Views: 2095

Answers (2)

Klay Martens
Klay Martens

Reputation: 13

So there is a bit of a trick to this - took some head scratching to get to it. The issue is that you have to pass the csrf to your blue print, which I do by initialising it on the app before adding the blue prints. Then import csrf on your blue print (safe only if the variable is initialised BEFORE you register your blue prints) Maybe this will help someone else...

so in your init.py, define csrf as a module variable, then initialise it BEFORE importing and configuring your blue prints

****
db: SQLAlchemy = SQLAlchemy()

app: Flask = None
csrf: CSRFProtect = None
****

def init_app():
    """Initialize the core application."""
    global app
    global csrf
    db.init_app(app)
    ****
    csrf = CSRFProtect(app)

    with app.app_context():
        # Include our Routes
        from routes import route
        ****
        # Register Blueprints
        app.register_blueprint(route.route_bp)
****

And then in route:

import Api.csrf

So, its basically the same idea as importing/sharing your App object.

Upvotes: 0

Renan Rosa
Renan Rosa

Reputation: 38

I have got this solved by marking a view or blueprint to be excluded from CSRF protection.

app = Flask(__name__)
csrf = CSRFProtect(app)


@app.route('/some-view', methods=['POST'])
@csrf.exempt
def some_view():
    ...

bp = Blueprint(...)
csrf.exempt(bp)

Upvotes: 2

Related Questions