maxcountryman / flask-seasurf

SeaSurf is a Flask extension for preventing cross-site request forgery (CSRF).
http://readthedocs.org/docs/flask-seasurf/
Other
190 stars 49 forks source link

Can't add exempt for Blueprints #134

Open marban opened 2 years ago

marban commented 2 years ago

Anyone got a hint how to add a Blueprint's route to the _exempt_views set? Something like csrf._exempt_views.add("bp_user.someroute") Importing the root @csrf.exempt decorator in the Blueprint doesn't seem to work either

psycle-dblakemore commented 1 year ago

Not sure whether you're still having an issue with this, but if you are, please provide a code sample. Generally speaking, you should be able to wrap a Blueprint's route function with @csrf.exempt like this:

from flask import Flask
from flask import Blueprint
from flask_seasurf import SeaSurf

app = Flask(__name__)
app.secret_key = "super secret key"
csrf = SeaSurf(app)

custom_blueprint = Blueprint('custom', __name__, url_prefix='/custom')

@csrf.exempt
@custom_blueprint.route('/exempt', methods=['POST'])
def exempt_route():
    return "This route is exempt from CSRF"

@custom_blueprint.route('/nonexempt', methods=['POST'])
def non_exempt_route():
    return "This route is not exempt from CSRF"

app.register_blueprint(custom_blueprint)

However depending on how you have you file structure set up, you might need to do something different. If you can provide some details on your specific problem (code examples), then I might be able to help further.

eheaton commented 8 months ago

I actually am running into the same issue, where I can't use the @csrf.exempt decorator in a blueprint. Here is a basic structure of what I'm trying to do:

# my_module/blueprint.py

from flask import Blueprint

bp = Blueprint('my_blueprint', __name__)

@bp.post("/test-blueprint-route")
@bp.csrf.exempt # <-- This throws an error
def post_test_blueprint_route():
    return { "success": True }
 # app.py
import Flask
from flask_seasurf import SeaSurf
from my_module.blueprint import bp

app = Flask(__name__)
app.secret_key = "super-secret-key"
app.csrf = SeaSurf(app)
app.register_blueprint(bp, url_prefix="/api")

@app.post("/test-route")
@app.csrf.exempt # <-- This does NOT throw an error
def post_test_route():
    return { "success": True }

The error I get is:

AttributeError: 'Blueprint' object has no attribute 'csrf'

Based on your above example it works because the csrf decorator is defined in the same file as the Blueprint, but that's generally not the case.

eheaton commented 8 months ago

I actually am running into the same issue, where I can't use the @csrf.exempt decorator in a blueprint. Here is a basic structure of what I'm trying to do:

# my_module/blueprint.py

from flask import Blueprint

bp = Blueprint('my_blueprint', __name__)

@bp.post("/test-blueprint-route")
@bp.csrf.exempt # <-- This throws an error
def post_test_blueprint_route():
    return { "success": True }
 # app.py
import Flask
from flask_seasurf import SeaSurf
from my_module.blueprint import bp

app = Flask(__name__)
app.secret_key = "super-secret-key"
app.csrf = SeaSurf(app)
app.register_blueprint(bp, url_prefix="/api")

@app.post("/test-route")
@app.csrf.exempt # <-- This does NOT throw an error
def post_test_route():
    return { "success": True }

The error I get is:

AttributeError: 'Blueprint' object has no attribute 'csrf'

Based on your above example it works because the csrf decorator is defined in the same file as the Blueprint, but that's generally not the case.