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)
More simple solution (related commit):
And here is a complete demo:
You could set WTF_CSRF_ENABLED = False in your test_config. If you only want to disable it for your tests that is.
You can use the
@csrf.exempt
decorator, which you need to add directly on the API object, with thedecorators
argument; this would apply the decorator to all API routes: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.
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.