Flask-Restful POST fails due CSRF protection of Fl

2020-05-23 20:13发布

I am using normal flask web + flask-restful. So I need CSRF protection for web but not for REST.

The moment I enable CsrfProtect(app) of flask-wtf, all my post unit tests for flask-restful return a 400.

Is there a way to disable CSRF protection for REST services since they are coming from mobile handsets without session handling anyway, hence CSRF wouldn't make much sense.

This is how I test it:

rv = self.client.post('api/v1.0/verify-email', environ_base={'REMOTE_ADDR': '127.0.0.1'}, headers={'Content-Type':'application/json'}, data=json.dumps(data))
self.check_content_type(rv.headers)
eq_(rv.status_code, 412)

4条回答
Juvenile、少年°
2楼-- · 2020-05-23 20:16

More simple solution (related commit):

csrf.exempt(api_blueprint)

And here is a complete demo:

from flask import Flask, Blueprint
from flask_wtf import CSRFProtect

app = Flask(__name__)
csrf = CSRFprotect(app)

api_blueprint = Blueprint('api', __name__)
csrf.exempt(api_blueprint)

app.register_blueprint(api_blueprint)
查看更多
贪生不怕死
3楼-- · 2020-05-23 20:22

You could set WTF_CSRF_ENABLED = False in your test_config. If you only want to disable it for your tests that is.

查看更多
Explosion°爆炸
4楼-- · 2020-05-23 20:27

You can use the @csrf.exempt decorator, which you need to add directly on the API object, with the decorators argument; this would apply the decorator to all API routes:

csrf_protect = CsrfProtect(app)
api = restful.Api(app, decorators=[csrf_protect.exempt])

You cannot use resource method decorators as they are not the final view functions that the exempt decorator requires to work.

It appears you cannot protect individual resources and exempt others; this is a limitation in the method used by Flask-Wtf's method of recording what views are exempted.

查看更多
做个烂人
5楼-- · 2020-05-23 20:39

I had the exact same issue and I kept getting a generic 401 Unauthorized error, while my postman calls were working absolutely fine. It took me a while to figure out that this was because I had enabled CSRF for my web-based forms. But my backend calls were served by Restful endpoints and CSRF Protection doesn't work with restful calls.

Here's how I fixed it:

In my settings file,

I set JWT_COOKIE_CSRF_PROTECT to False and that fixed my restful post calls.

Note:

Since you are setting this field in the global settings file, this action will disable CSRF Protection for all the API calls.

查看更多
登录 后发表回答