Skip to content

Commit 1d1e55d

Browse files
committed
Add config option for JWT expire length #44
1 parent 816f121 commit 1d1e55d

8 files changed

+166
-96
lines changed

README.md

+20
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ from flask import Flask
2828
from flask_jwt_router import JwtRoutes
2929

3030
app = Flask(__name__)
31+
# You are required to always set a unique SECRET_KEY for your app
32+
app.config["SECRET_KEY"] = "your_app_secret_key"
3133

3234
JwtRoutes(app)
3335

@@ -177,6 +179,24 @@ If you are handling a request without a token in the headers you can call::
177179
jwt_routes.create_token(entity_id=user_data.id, table_name="users")
178180
```
179181

182+
# Setting the Token Expire Duration
183+
There are two ways to set the expire duration of the JWT.
184+
185+
from your app config
186+
```python
187+
# Set the token expire duration to 7 days
188+
app.config["JWT_EXPIRE_DAYS"] = 7
189+
```
190+
calling the `set_exp`
191+
```python
192+
193+
# Set the token expire duration to 14 days
194+
jwt_routes = JwtRoutes()
195+
# jwt_routes.init_app( ...etc
196+
jwt_routes.set_exp(expire_days=14)
197+
```
198+
By default the expire duration is set to 30 days
199+
180200
An Example configuration for registering & logging in users of different types:
181201
```python
182202
app.config["IGNORED_ROUTES"] = [("GET", "/")]

flask_jwt_router/_config.py

+19-10
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,14 @@ def __init__(self):
1616

1717

1818
class _Config:
19-
"""
20-
:param secret_key: User defined secret key
21-
:param entity_key: The name of the model's entity attribute
22-
:param whitelist_routes: List of tuple pairs of verb & url path
23-
:param api_name: the api name prefix e.g `/api/v1`
24-
:param ignored_routes: Opt our routes from api name prefixing
25-
:param entity_models: Multiple entities to be authenticated
26-
"""
2719
def __init__(self,
2820
secret_key=None,
2921
entity_key="id",
3022
whitelist_routes=None,
3123
api_name=None,
3224
ignored_routes=None,
3325
entity_models=None,
26+
expire_days=None,
3427
):
3528

3629
self.secret_key = secret_key
@@ -39,24 +32,38 @@ def __init__(self,
3932
self.api_name = api_name
4033
self.ignored_routes = ignored_routes
4134
self.entity_models = entity_models
35+
self.expire_days = expire_days
4236

4337

4438
class BaseConfig(ABC):
4539
"""Abstract Base Class for Extensions"""
40+
41+
def __init__(self):
42+
self.expire_days = None
43+
4644
@abstractmethod
4745
def init_config(self, config: Dict[str, Any], **kwargs) -> None:
4846
# pylint: disable=missing-function-docstring
4947
pass
5048

5149

5250
class Config(BaseConfig):
53-
"""Contains the main configuration values"""
54-
entity_models: List[_ORMType]
51+
"""
52+
:param secret_key: User defined secret key
53+
:param entity_key: The name of the model's entity attribute
54+
:param whitelist_routes: List of tuple pairs of verb & url path
55+
:param api_name: the api name prefix e.g `/api/v1`
56+
:param ignored_routes: Opt our routes from api name prefixing
57+
:param entity_models: Multiple entities to be authenticated
58+
:param expire_days: Expire time for the token in days
59+
"""
5560
secret_key: str
5661
entity_key: str
5762
whitelist_routes: List[Tuple[str]]
5863
api_name: str
5964
ignored_routes: List[Tuple[str]]
65+
entity_models: List[_ORMType]
66+
expire_days: int
6067

6168
def init_config(self, app_config: Dict[str, Any], **kwargs) -> None:
6269
"""
@@ -71,6 +78,7 @@ def init_config(self, app_config: Dict[str, Any], **kwargs) -> None:
7178
app_config.get("JWT_ROUTER_API_NAME"),
7279
app_config.get("IGNORED_ROUTES") or [],
7380
entity_models or app_config.get("ENTITY_MODELS") or [],
81+
app_config.get("JWT_EXPIRE_DAYS")
7482
)
7583
if not _config.secret_key:
7684
raise SecretKeyError
@@ -81,3 +89,4 @@ def init_config(self, app_config: Dict[str, Any], **kwargs) -> None:
8189
self.api_name = _config.api_name
8290
self.ignored_routes = _config.ignored_routes
8391
self.entity_models = _config.entity_models
92+
self.expire_days = _config.expire_days

flask_jwt_router/_jwt_routes.py

+34-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from flask_jwt_router import JwtRoutes
1414
1515
app = Flask(__name__)
16+
# You are required to always set a unique SECRET_KEY for your app
17+
app.config["SECRET_KEY"] = "your_app_secret_key"
1618
1719
JwtRoutes(app)
1820
@@ -77,6 +79,24 @@ def create_app(config):
7779
...
7880
jwt_routes.init_app(app, entity_models=[UserModel, TeacherModel, ...etc])
7981
82+
Setting the Token Expire Duration
83+
=================================
84+
85+
There are two ways to set the expire duration of the JWT.
86+
87+
from your app config::
88+
89+
# Set the token expire duration to 7 days
90+
app.config["JWT_EXPIRE_DAYS"] = 7
91+
92+
using the :class:`~flask_jwt_router.set_exp` method::
93+
94+
# Set the token expire duration to 14 days
95+
jwt_routes = JwtRoutes()
96+
# jwt_routes.init_app( ...etc
97+
jwt_routes.set_exp(expire_days=14)
98+
99+
By default the expire duration is set to 30 days
80100
81101
Authorization & Tokens
82102
======================
@@ -163,6 +183,8 @@ def login():
163183
# pylint:disable=invalid-name
164184
logger = logging.getLogger()
165185

186+
EXPIRE_DEFAULT = 30
187+
166188

167189
class JwtRoutes:
168190
"""
@@ -180,8 +202,9 @@ class JwtRoutes:
180202
#: A list of entity models
181203
entity_models: List[_ORMType]
182204

183-
#: Token expiry value. eg. 30 = 30 days from creation date.
184-
exp: int = 30
205+
#: Low level expire member. See :class:`~flask_jwt_router._config` & set with JWT_EXPIRE_DAYS
206+
#: or use :class:`~flask_jwt_router.set_exp`.
207+
exp: int
185208

186209
#: The class that is used to create Config objects. See :class:`~flask_jwt_router._config`
187210
#: for more information.
@@ -224,6 +247,10 @@ def init_app(self, app=None, **kwargs):
224247
self.entity = Entity(self.config)
225248
self.routing = Routing(self.app, self.config, self.entity)
226249
self.app.before_request(self.routing.before_middleware)
250+
if self.config.expire_days:
251+
self.exp = self.config.expire_days
252+
else:
253+
self.exp = EXPIRE_DEFAULT
227254

228255
# pylint:disable=no-self-use
229256
def get_app_config(self, app):
@@ -246,15 +273,16 @@ def get_entity_id(self, **kwargs):
246273
return None
247274

248275
# pylint:disable=no-self-use
249-
def get_exp(self, **kwargs):
276+
def set_exp(self, **kwargs) -> None:
250277
"""
251278
:param kwargs: Dict[str, int]
252-
:return: number
279+
- expire_days: The expire time for the JWT in days
280+
:return: None
253281
"""
254282
try:
255-
return kwargs['exp']
283+
self.exp = kwargs['expire_days']
256284
except KeyError as _:
257-
return 30
285+
self.exp = EXPIRE_DEFAULT
258286

259287
def create_token(self, **kwargs) -> str:
260288
"""

source/flask_jwt_router.rst

-4
This file was deleted.

source/index.rst

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ Welcome to Flask JWT Router
1414
authentication
1515
entity
1616
config
17-
flask_jwt_router
1817
routing
1918

2019

tests/test_config.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class TestConfig:
1818
"SECRET_KEY": "a sectrect key",
1919
"JWT_ROUTER_API_NAME": "api/v1",
2020
"ENTITY_KEY": "user_id",
21+
"JWT_EXPIRE_DAYS": 6,
2122
}
2223

2324
def test_init_config(self, MockEntityModel):
@@ -29,8 +30,9 @@ def test_init_config(self, MockEntityModel):
2930
assert config.entity_models == [MockEntityModel]
3031
assert config.entity_key == "user_id"
3132
assert config.api_name == "api/v1"
33+
assert config.expire_days == 6
3234

3335
config_two = {**self.config, "ENTITY_MODELS": [MockEntityModel]}
3436
config.init_config(config_two)
3537

36-
assert config.entity_models == [MockEntityModel]
38+
assert config.entity_models == [MockEntityModel]

tests/test_jwt_router.py

-73
This file was deleted.

0 commit comments

Comments
 (0)