Skip to content

Commit

Permalink
Merge pull request #36 from crw/master
Browse files Browse the repository at this point in the history
Iss #35 Added a config option to control setting session or persisten…
  • Loading branch information
vimalloc authored Apr 5, 2017
2 parents 8f57733 + 09ac2df commit 21345d8
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 2 deletions.
2 changes: 2 additions & 0 deletions docs/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ The available options are:
``JWT_REFRESH_COOKIE_PATH`` What ``path`` should be set for the refresh cookie. Defaults to ``None``, which
will cause this access cookie to be sent in with every request. Should be modified
for only the paths that need the refresh cookie
``JWT_SESSION_COOKIE`` Whether to set session (deleted when the browser is closed) or persistent cookies.
Defaults to ``True`` (sets session cookies).
``JWT_COOKIE_CSRF_PROTECT`` Enable/disable CSRF protection. Only used when sending the JWT in via cookies
``JWT_CSRF_METHODS`` The request types that will use CSRF protection. Defaults to
```['POST', 'PUT', 'PATCH', 'DELETE']```
Expand Down
5 changes: 5 additions & 0 deletions flask_jwt_extended/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
REFRESH_COOKIE_NAME = 'refresh_token_cookie'
ACCESS_COOKIE_PATH = None
REFRESH_COOKIE_PATH = None
SESSION_COOKIE = True # True to use session cookies, False to use persistent

# Options for using double submit for verifying CSRF tokens
COOKIE_CSRF_PROTECT = True
Expand Down Expand Up @@ -76,6 +77,10 @@ def get_refresh_cookie_path():
return current_app.config.get('JWT_REFRESH_COOKIE_PATH', REFRESH_COOKIE_PATH)


def get_session_cookie():
return current_app.config.get('JWT_SESSION_COOKIE', SESSION_COOKIE)


def get_cookie_csrf_protect():
return current_app.config.get('JWT_COOKIE_CSRF_PROTECT', COOKIE_CSRF_PROTECT)

Expand Down
14 changes: 13 additions & 1 deletion flask_jwt_extended/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
get_algorithm, get_blacklist_enabled, get_blacklist_checks, get_jwt_header_type, \
get_access_cookie_name, get_cookie_secure, get_access_cookie_path, \
get_cookie_csrf_protect, get_access_csrf_cookie_name, \
get_refresh_cookie_name, get_refresh_cookie_path, \
get_refresh_cookie_name, get_refresh_cookie_path, get_session_cookie, \
get_refresh_csrf_cookie_name, get_token_location, \
get_csrf_header_name, get_jwt_header_name, get_csrf_request_methods
from flask_jwt_extended.exceptions import JWTEncodeError, JWTDecodeError, \
Expand Down Expand Up @@ -49,6 +49,14 @@ def get_raw_jwt():
return getattr(ctx_stack.top, 'jwt', {})


def _get_cookie_max_age():
"""
Checks config value for using session or persistent cookies and returns the
appropriate value for flask set_cookies.
"""
return None if get_session_cookie() else 2147483647 # 2^31


def _create_csrf_token():
return str(uuid.uuid4())

Expand Down Expand Up @@ -395,6 +403,7 @@ def set_access_cookies(response, encoded_access_token):
# Set the access JWT in the cookie
response.set_cookie(get_access_cookie_name(),
value=encoded_access_token,
max_age=_get_cookie_max_age(),
secure=get_cookie_secure(),
httponly=True,
path=get_access_cookie_path())
Expand All @@ -403,6 +412,7 @@ def set_access_cookies(response, encoded_access_token):
if get_cookie_csrf_protect():
response.set_cookie(get_access_csrf_cookie_name(),
value=_get_csrf_token(encoded_access_token),
max_age=_get_cookie_max_age(),
secure=get_cookie_secure(),
httponly=False,
path='/')
Expand All @@ -420,6 +430,7 @@ def set_refresh_cookies(response, encoded_refresh_token):
# Set the refresh JWT in the cookie
response.set_cookie(get_refresh_cookie_name(),
value=encoded_refresh_token,
max_age=_get_cookie_max_age(),
secure=get_cookie_secure(),
httponly=True,
path=get_refresh_cookie_path())
Expand All @@ -428,6 +439,7 @@ def set_refresh_cookies(response, encoded_refresh_token):
if get_cookie_csrf_protect():
response.set_cookie(get_refresh_csrf_cookie_name(),
value=_get_csrf_token(encoded_refresh_token),
max_age=_get_cookie_max_age(),
secure=get_cookie_secure(),
httponly=False,
path='/')
Expand Down
5 changes: 4 additions & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
get_token_location, get_cookie_secure, get_access_cookie_name, \
get_refresh_cookie_name, get_access_cookie_path, get_refresh_cookie_path, \
get_cookie_csrf_protect, get_access_csrf_cookie_name, \
get_refresh_csrf_cookie_name, get_csrf_header_name
get_refresh_csrf_cookie_name, get_csrf_header_name, get_session_cookie
from flask_jwt_extended import JWTManager


Expand All @@ -34,6 +34,7 @@ def test_default_configs(self):
self.assertEqual(get_refresh_cookie_name(), 'refresh_token_cookie')
self.assertEqual(get_access_cookie_path(), None)
self.assertEqual(get_refresh_cookie_path(), None)
self.assertEqual(get_session_cookie(), True)
self.assertEqual(get_cookie_csrf_protect(), True)
self.assertEqual(get_access_csrf_cookie_name(), 'csrf_access_token')
self.assertEqual(get_refresh_csrf_cookie_name(), 'csrf_refresh_token')
Expand All @@ -56,6 +57,7 @@ def test_override_configs(self):
self.app.config['JWT_REFRESH_COOKIE_NAME'] = 'banana2'
self.app.config['JWT_ACCESS_COOKIE_PATH'] = '/banana/'
self.app.config['JWT_REFRESH_COOKIE_PATH'] = '/banana2/'
self.app.config['JWT_SESSION_COOKIE'] = False
self.app.config['JWT_COOKIE_CSRF_PROTECT'] = False
self.app.config['JWT_ACCESS_CSRF_COOKIE_NAME'] = 'banana1a'
self.app.config['JWT_REFRESH_CSRF_COOKIE_NAME'] = 'banana2a'
Expand All @@ -78,6 +80,7 @@ def test_override_configs(self):
self.assertEqual(get_refresh_cookie_name(), 'banana2')
self.assertEqual(get_access_cookie_path(), '/banana/')
self.assertEqual(get_refresh_cookie_path(), '/banana2/')
self.assertEqual(get_session_cookie(), False)
self.assertEqual(get_cookie_csrf_protect(), False)
self.assertEqual(get_access_csrf_cookie_name(), 'banana1a')
self.assertEqual(get_refresh_csrf_cookie_name(), 'banana2a')
Expand Down

0 comments on commit 21345d8

Please sign in to comment.