Skip to content

Commit 1a3ce7c

Browse files
author
Landon Gilbert-Bland
committed
Fix CSRF error on JWT optional (#129)
1 parent b7c8219 commit 1a3ce7c

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

flask_jwt_extended/view_decorators.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,17 @@ def _decode_jwt_from_cookies(request_type):
156156
cookie_key = config.refresh_cookie_name
157157
csrf_header_key = config.refresh_csrf_header_name
158158

159+
encoded_token = request.cookies.get(cookie_key)
160+
if not encoded_token:
161+
raise NoAuthorizationError('Missing cookie "{}"'.format(cookie_key))
162+
159163
if config.csrf_protect and request.method in config.csrf_request_methods:
160164
csrf_value = request.headers.get(csrf_header_key, None)
161165
if not csrf_value:
162166
raise CSRFError("Missing CSRF token in headers")
163167
else:
164168
csrf_value = None
165169

166-
encoded_token = request.cookies.get(cookie_key)
167-
if not encoded_token:
168-
raise NoAuthorizationError('Missing cookie "{}"'.format(cookie_key))
169-
170170
return decode_token(encoded_token, csrf_value=csrf_value)
171171

172172

tests/test_cookies.py

+24-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from flask_jwt_extended import (
55
jwt_required, JWTManager, jwt_refresh_token_required, create_access_token,
66
create_refresh_token, set_access_cookies, set_refresh_cookies,
7-
unset_jwt_cookies
7+
unset_jwt_cookies, jwt_optional
88
)
99

1010
def _get_cookie_from_response(response, cookie_name):
@@ -66,6 +66,11 @@ def refresh_protected():
6666
def post_refresh_protected():
6767
return jsonify(foo='bar')
6868

69+
@app.route('/optional_post_protected', methods=['POST'])
70+
@jwt_optional
71+
def optional_post_protected():
72+
return jsonify(foo='bar')
73+
6974
return app
7075

7176

@@ -391,3 +396,21 @@ def test_cookies_without_csrf(app):
391396
assert len(cookies) == 1
392397
refresh_cookie = _get_cookie_from_response(response, 'refresh_token_cookie')
393398
assert refresh_cookie is not None
399+
400+
def test_jwt_optional_with_csrf_enabled(app):
401+
test_client = app.test_client()
402+
403+
# User without a token should be able to reach the endpoint without
404+
# getting a CSRF error
405+
response = test_client.post('/optional_post_protected')
406+
json_data = json.loads(response.get_data(as_text=True))
407+
assert response.status_code == 200
408+
assert json_data == {'foo': 'bar'}
409+
410+
# User with a token should still get a CSRF error if csrf not present
411+
response = test_client.get('/access_token')
412+
csrf_token = _get_cookie_from_response(response, 'csrf_access_token')['csrf_access_token']
413+
response = test_client.post('/optional_post_protected')
414+
json_data = json.loads(response.get_data(as_text=True))
415+
assert response.status_code == 401
416+
assert json_data == {'msg': 'Missing CSRF token in headers'}

0 commit comments

Comments
 (0)