Skip to content

Commit 21345d8

Browse files
authored
Merge pull request #36 from crw/master
Iss #35 Added a config option to control setting session or persisten…
2 parents 8f57733 + 09ac2df commit 21345d8

File tree

4 files changed

+24
-2
lines changed

4 files changed

+24
-2
lines changed

docs/options.rst

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ The available options are:
3232
``JWT_REFRESH_COOKIE_PATH`` What ``path`` should be set for the refresh cookie. Defaults to ``None``, which
3333
will cause this access cookie to be sent in with every request. Should be modified
3434
for only the paths that need the refresh cookie
35+
``JWT_SESSION_COOKIE`` Whether to set session (deleted when the browser is closed) or persistent cookies.
36+
Defaults to ``True`` (sets session cookies).
3537
``JWT_COOKIE_CSRF_PROTECT`` Enable/disable CSRF protection. Only used when sending the JWT in via cookies
3638
``JWT_CSRF_METHODS`` The request types that will use CSRF protection. Defaults to
3739
```['POST', 'PUT', 'PATCH', 'DELETE']```

flask_jwt_extended/config.py

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
REFRESH_COOKIE_NAME = 'refresh_token_cookie'
1616
ACCESS_COOKIE_PATH = None
1717
REFRESH_COOKIE_PATH = None
18+
SESSION_COOKIE = True # True to use session cookies, False to use persistent
1819

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

7879

80+
def get_session_cookie():
81+
return current_app.config.get('JWT_SESSION_COOKIE', SESSION_COOKIE)
82+
83+
7984
def get_cookie_csrf_protect():
8085
return current_app.config.get('JWT_COOKIE_CSRF_PROTECT', COOKIE_CSRF_PROTECT)
8186

flask_jwt_extended/utils.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
get_algorithm, get_blacklist_enabled, get_blacklist_checks, get_jwt_header_type, \
1717
get_access_cookie_name, get_cookie_secure, get_access_cookie_path, \
1818
get_cookie_csrf_protect, get_access_csrf_cookie_name, \
19-
get_refresh_cookie_name, get_refresh_cookie_path, \
19+
get_refresh_cookie_name, get_refresh_cookie_path, get_session_cookie, \
2020
get_refresh_csrf_cookie_name, get_token_location, \
2121
get_csrf_header_name, get_jwt_header_name, get_csrf_request_methods
2222
from flask_jwt_extended.exceptions import JWTEncodeError, JWTDecodeError, \
@@ -49,6 +49,14 @@ def get_raw_jwt():
4949
return getattr(ctx_stack.top, 'jwt', {})
5050

5151

52+
def _get_cookie_max_age():
53+
"""
54+
Checks config value for using session or persistent cookies and returns the
55+
appropriate value for flask set_cookies.
56+
"""
57+
return None if get_session_cookie() else 2147483647 # 2^31
58+
59+
5260
def _create_csrf_token():
5361
return str(uuid.uuid4())
5462

@@ -395,6 +403,7 @@ def set_access_cookies(response, encoded_access_token):
395403
# Set the access JWT in the cookie
396404
response.set_cookie(get_access_cookie_name(),
397405
value=encoded_access_token,
406+
max_age=_get_cookie_max_age(),
398407
secure=get_cookie_secure(),
399408
httponly=True,
400409
path=get_access_cookie_path())
@@ -403,6 +412,7 @@ def set_access_cookies(response, encoded_access_token):
403412
if get_cookie_csrf_protect():
404413
response.set_cookie(get_access_csrf_cookie_name(),
405414
value=_get_csrf_token(encoded_access_token),
415+
max_age=_get_cookie_max_age(),
406416
secure=get_cookie_secure(),
407417
httponly=False,
408418
path='/')
@@ -420,6 +430,7 @@ def set_refresh_cookies(response, encoded_refresh_token):
420430
# Set the refresh JWT in the cookie
421431
response.set_cookie(get_refresh_cookie_name(),
422432
value=encoded_refresh_token,
433+
max_age=_get_cookie_max_age(),
423434
secure=get_cookie_secure(),
424435
httponly=True,
425436
path=get_refresh_cookie_path())
@@ -428,6 +439,7 @@ def set_refresh_cookies(response, encoded_refresh_token):
428439
if get_cookie_csrf_protect():
429440
response.set_cookie(get_refresh_csrf_cookie_name(),
430441
value=_get_csrf_token(encoded_refresh_token),
442+
max_age=_get_cookie_max_age(),
431443
secure=get_cookie_secure(),
432444
httponly=False,
433445
path='/')

tests/test_config.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
get_token_location, get_cookie_secure, get_access_cookie_name, \
1111
get_refresh_cookie_name, get_access_cookie_path, get_refresh_cookie_path, \
1212
get_cookie_csrf_protect, get_access_csrf_cookie_name, \
13-
get_refresh_csrf_cookie_name, get_csrf_header_name
13+
get_refresh_csrf_cookie_name, get_csrf_header_name, get_session_cookie
1414
from flask_jwt_extended import JWTManager
1515

1616

@@ -34,6 +34,7 @@ def test_default_configs(self):
3434
self.assertEqual(get_refresh_cookie_name(), 'refresh_token_cookie')
3535
self.assertEqual(get_access_cookie_path(), None)
3636
self.assertEqual(get_refresh_cookie_path(), None)
37+
self.assertEqual(get_session_cookie(), True)
3738
self.assertEqual(get_cookie_csrf_protect(), True)
3839
self.assertEqual(get_access_csrf_cookie_name(), 'csrf_access_token')
3940
self.assertEqual(get_refresh_csrf_cookie_name(), 'csrf_refresh_token')
@@ -56,6 +57,7 @@ def test_override_configs(self):
5657
self.app.config['JWT_REFRESH_COOKIE_NAME'] = 'banana2'
5758
self.app.config['JWT_ACCESS_COOKIE_PATH'] = '/banana/'
5859
self.app.config['JWT_REFRESH_COOKIE_PATH'] = '/banana2/'
60+
self.app.config['JWT_SESSION_COOKIE'] = False
5961
self.app.config['JWT_COOKIE_CSRF_PROTECT'] = False
6062
self.app.config['JWT_ACCESS_CSRF_COOKIE_NAME'] = 'banana1a'
6163
self.app.config['JWT_REFRESH_CSRF_COOKIE_NAME'] = 'banana2a'
@@ -78,6 +80,7 @@ def test_override_configs(self):
7880
self.assertEqual(get_refresh_cookie_name(), 'banana2')
7981
self.assertEqual(get_access_cookie_path(), '/banana/')
8082
self.assertEqual(get_refresh_cookie_path(), '/banana2/')
83+
self.assertEqual(get_session_cookie(), False)
8184
self.assertEqual(get_cookie_csrf_protect(), False)
8285
self.assertEqual(get_access_csrf_cookie_name(), 'banana1a')
8386
self.assertEqual(get_refresh_csrf_cookie_name(), 'banana2a')

0 commit comments

Comments
 (0)