Skip to content

Commit

Permalink
Add "iat" claim to token (#192)
Browse files Browse the repository at this point in the history
Co-authored-by: mizvyt <vytautas@anqlave.co>
  • Loading branch information
mizvyt and mizvyt committed Oct 1, 2021
1 parent 9b06293 commit 7759aa8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
4 changes: 3 additions & 1 deletion rest_framework_simplejwt/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def validate(self, attrs):

refresh.set_jti()
refresh.set_exp()
refresh.set_iat()

data['refresh'] = str(refresh)

Expand All @@ -133,8 +134,9 @@ def validate(self, attrs):
# passed
token.check_exp(api_settings.SLIDING_TOKEN_REFRESH_EXP_CLAIM)

# Update the "exp" claim
# Update the "exp" and "iat" claims
token.set_exp()
token.set_iat()

return {'token': str(token)}

Expand Down
18 changes: 17 additions & 1 deletion rest_framework_simplejwt/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ def __init__(self, token=None, verify=True):
# New token. Skip all the verification steps.
self.payload = {api_settings.TOKEN_TYPE_CLAIM: self.token_type}

# Set "exp" claim with default value
# Set "exp" and "iat" claims with default value
self.set_exp(from_time=self.current_time, lifetime=self.lifetime)
self.set_iat(at_time=self.current_time)

# Set "jti" claim
self.set_jti()
Expand Down Expand Up @@ -124,6 +125,9 @@ def set_jti(self):
def set_exp(self, claim='exp', from_time=None, lifetime=None):
"""
Updates the expiration time of a token.
See here:
https://tools.ietf.org/html/rfc7519#section-4.1.4
"""
if from_time is None:
from_time = self.current_time
Expand All @@ -133,6 +137,18 @@ def set_exp(self, claim='exp', from_time=None, lifetime=None):

self.payload[claim] = datetime_to_epoch(from_time + lifetime)

def set_iat(self, claim='iat', at_time=None):
"""
Updates the time at which the token was issued.
See here:
https://tools.ietf.org/html/rfc7519#section-4.1.6
"""
if at_time is None:
at_time = self.current_time

self.payload[claim] = datetime_to_epoch(at_time)

def check_exp(self, claim='exp', current_time=None):
"""
Checks whether a timestamp value in the given claim has passed (since
Expand Down
24 changes: 21 additions & 3 deletions tests/test_tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ def test_init_no_token_given(self):
self.assertEqual(t.current_time, now)
self.assertIsNone(t.token)

self.assertEqual(len(t.payload), 3)
self.assertEqual(t.payload['exp'], datetime_to_epoch(now + MyToken.lifetime))
self.assertEqual(len(t.payload), 4)
self.assertEqual(t.payload['exp'], datetime_to_epoch(now + MyToken.lifetime))
self.assertEqual(t.payload['iat'], datetime_to_epoch(now))
self.assertIn('jti', t.payload)
self.assertEqual(t.payload[api_settings.TOKEN_TYPE_CLAIM], MyToken.token_type)

Expand All @@ -88,9 +89,10 @@ def test_init_token_given(self):
self.assertEqual(t.current_time, now)
self.assertEqual(t.token, encoded_good_token)

self.assertEqual(len(t.payload), 4)
self.assertEqual(len(t.payload), 5)
self.assertEqual(t['some_value'], 'arst')
self.assertEqual(t['exp'], datetime_to_epoch(original_now + MyToken.lifetime))
self.assertEqual(t['iat'], datetime_to_epoch(original_now))
self.assertEqual(t[api_settings.TOKEN_TYPE_CLAIM], MyToken.token_type)
self.assertIn('jti', t.payload)

Expand Down Expand Up @@ -169,6 +171,7 @@ def test_str(self):
# content.
del token[api_settings.TOKEN_TYPE_CLAIM]
del token['jti']
del token['iat']

# Should encode the given token
encoded_token = str(token)
Expand Down Expand Up @@ -236,6 +239,21 @@ def test_set_exp(self):
self.assertIn('refresh_exp', token)
self.assertEqual(token['refresh_exp'], datetime_to_epoch(now + timedelta(days=1)))

def test_set_iat(self):
now = make_utc(datetime(year=2000, month=1, day=1))

token = MyToken()
token.current_time = now

# By default, should add 'iat' claim to token using `self.current_time`
token.set_iat()
self.assertEqual(token['iat'], datetime_to_epoch(now))

# Should allow overriding of time and claim name
token.set_iat(claim='refresh_iat', at_time=now + timedelta(days=1))
self.assertIn('refresh_iat', token)
self.assertEqual(token['refresh_iat'], datetime_to_epoch(now + timedelta(days=1)))

def test_check_exp(self):
token = MyToken()

Expand Down

0 comments on commit 7759aa8

Please sign in to comment.