Skip to content

Commit 5f35de0

Browse files
committed
Add possibility to configure user claims location (refs #90)
1 parent 92ac894 commit 5f35de0

File tree

7 files changed

+17
-6
lines changed

7 files changed

+17
-6
lines changed

docs/options.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ General Options:
3535
``JWT_IDENTITY_CLAIM`` Claim in the tokens that is used as source of identity.
3636
For interoperativity, the JWT RFC recommends using ``'sub'``.
3737
Defaults to ``'identity'`` for legacy reasons.
38+
``JWT_USER_CLAIMS`` Claim in the tokens that is used to store user claims.
39+
Defaults to ``'user_claims'``.
3840
================================= =========================================
3941

4042

flask_jwt_extended/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ def cookie_max_age(self):
227227
def identity_claim(self):
228228
return current_app.config['JWT_IDENTITY_CLAIM']
229229

230+
@property
231+
def user_claims(self):
232+
return current_app.config['JWT_USER_CLAIMS']
233+
230234
config = _Config()
231235

232236

flask_jwt_extended/jwt_manager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ def _set_default_configuration_options(app):
185185
app.config.setdefault('JWT_BLACKLIST_TOKEN_CHECKS', ['access', 'refresh'])
186186

187187
app.config.setdefault('JWT_IDENTITY_CLAIM', 'identity')
188+
app.config.setdefault('JWT_USER_CLAIMS', 'user_claims')
188189

189190
def user_claims_loader(self, callback):
190191
"""

flask_jwt_extended/tokens.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import jwt
55

66
from flask_jwt_extended.exceptions import JWTDecodeError
7+
from flask_jwt_extended.config import config
78

89

910
def _create_csrf_token():
@@ -52,7 +53,7 @@ def encode_access_token(identity, secret, algorithm, expires_delta, fresh,
5253

5354
# Add `user_claims` only is not empty or None.
5455
if user_claims:
55-
token_data['user_claims'] = user_claims
56+
token_data[config.user_claims] = user_claims
5657

5758
if csrf:
5859
token_data['csrf'] = _create_csrf_token()
@@ -107,8 +108,8 @@ def decode_jwt(encoded_token, secret, algorithm, csrf, identity_claim):
107108
if data['type'] == 'access':
108109
if 'fresh' not in data:
109110
raise JWTDecodeError("Missing claim: fresh")
110-
if 'user_claims' not in data:
111-
data['user_claims'] = {}
111+
if config.user_claims not in data:
112+
data[config.user_claims] = {}
112113
if csrf:
113114
if 'csrf' not in data:
114115
raise JWTDecodeError("Missing claim: csrf")

flask_jwt_extended/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def get_jwt_claims():
3737
in the JWT that is accessing the endpoint. If no custom user claims are
3838
present, an empty dict is returned instead.
3939
"""
40-
return get_raw_jwt().get('user_claims', {})
40+
return get_raw_jwt().get(config.user_claims, {})
4141

4242

4343
def get_current_user():

flask_jwt_extended/view_decorators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ def _decode_jwt_from_request(request_type):
216216

217217
# Check if the custom claims in access tokens are valid
218218
if request_type == 'access':
219-
if not verify_token_claims(decoded_token['user_claims']):
220-
raise UserClaimsVerificationError('user_claims verification failed')
219+
if not verify_token_claims(decoded_token[config.user_claims]):
220+
raise UserClaimsVerificationError('User claims verification failed')
221221

222222
# If blacklisting is enabled, see if this token has been revoked
223223
if _token_blacklisted(decoded_token, request_type):

tests/test_config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def test_default_configs(self):
5555
self.assertEqual(config.cookie_max_age, None)
5656

5757
self.assertEqual(config.identity_claim, 'identity')
58+
self.assertEqual(config.user_claims, 'user_claims')
5859

5960
def test_override_configs(self):
6061
self.app.config['JWT_TOKEN_LOCATION'] = ['cookies']
@@ -89,6 +90,7 @@ def test_override_configs(self):
8990
self.app.secret_key = 'banana'
9091

9192
self.app.config['JWT_IDENTITY_CLAIM'] = 'foo'
93+
self.app.config['JWT_USER_CLAIMS'] = 'bar'
9294

9395
with self.app.test_request_context():
9496
self.assertEqual(config.token_location, ['cookies'])
@@ -127,6 +129,7 @@ def test_override_configs(self):
127129
self.assertEqual(config.cookie_max_age, 2147483647)
128130

129131
self.assertEqual(config.identity_claim, 'foo')
132+
self.assertEqual(config.user_claims, 'bar')
130133

131134
def test_invalid_config_options(self):
132135
with self.app.test_request_context():

0 commit comments

Comments
 (0)