diff --git a/docs/index.md b/docs/index.md index 0372ae93..5bc5c9f7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -127,6 +127,8 @@ JWT_AUTH = { 'JWT_VERIFY_EXPIRATION': True, 'JWT_LEEWAY': 0, 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300), + 'JWT_AUDIENCE': None, + 'JWT_ISSUER': None, 'JWT_ALLOW_REFRESH': False, 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7), @@ -182,6 +184,16 @@ This is an instance of Python's `datetime.timedelta`. This will be added to `dat Default is `datetime.timedelta(seconds=300)`(5 minutes). +### JWT_AUDIENCE +This is a string that will be checked against the `aud` field of the token, if present. + +Default is `None`(fail if `aud` present on JWT). + +### JWT_ISSUER +This is a string that will be checked against the `iss` field of the token. + +Default is `None`(do not check `iss` on JWT). + ### JWT_ALLOW_REFRESH Enable token refresh functionality. Token issued from `rest_framework_jwt.views.obtain_jwt_token` will have an `orig_iat` field. Default is `False` diff --git a/rest_framework_jwt/settings.py b/rest_framework_jwt/settings.py index 5cb038d7..178b4f21 100644 --- a/rest_framework_jwt/settings.py +++ b/rest_framework_jwt/settings.py @@ -28,6 +28,8 @@ 'JWT_VERIFY_EXPIRATION': True, 'JWT_LEEWAY': 0, 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300), + 'JWT_AUDIENCE': None, + 'JWT_ISSUER': None, 'JWT_ALLOW_REFRESH': False, 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7), diff --git a/rest_framework_jwt/utils.py b/rest_framework_jwt/utils.py index 72687a7f..71f4ad16 100644 --- a/rest_framework_jwt/utils.py +++ b/rest_framework_jwt/utils.py @@ -52,7 +52,9 @@ def jwt_decode_handler(token): api_settings.JWT_SECRET_KEY, api_settings.JWT_VERIFY, verify_expiration=api_settings.JWT_VERIFY_EXPIRATION, - leeway=api_settings.JWT_LEEWAY + leeway=api_settings.JWT_LEEWAY, + audience=api_settings.JWT_AUDIENCE, + issuer=api_settings.JWT_ISSUER ) diff --git a/tests/test_utils.py b/tests/test_utils.py index de028f49..421876fe 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -3,7 +3,9 @@ from django.contrib.auth import get_user_model from django.test import TestCase +import jwt.exceptions from rest_framework_jwt import utils +from rest_framework_jwt.settings import api_settings, DEFAULTS User = get_user_model() @@ -54,3 +56,71 @@ def test_jwt_response_payload(self): response_data = utils.jwt_response_payload_handler(token, self.user) self.assertEqual(response_data, dict(token=token)) + + +class TestAudience(TestCase): + def setUp(self): + api_settings.JWT_AUDIENCE = "my_aud" + + self.username = 'jpueblo' + self.email = 'jpueblo@example.com' + self.user = User.objects.create_user(self.username, self.email) + + return super(TestAudience, self).setUp() + + def test_fail_audience_missing(self): + payload = utils.jwt_payload_handler(self.user) + token = utils.jwt_encode_handler(payload) + with self.assertRaises(jwt.exceptions.InvalidAudienceError): + utils.jwt_decode_handler(token) + + def test_fail_audience_wrong(self): + payload = utils.jwt_payload_handler(self.user) + payload['aud'] = "my_aud2" + token = utils.jwt_encode_handler(payload) + with self.assertRaises(jwt.exceptions.InvalidAudienceError): + utils.jwt_decode_handler(token) + + def test_correct_audience(self): + payload = utils.jwt_payload_handler(self.user) + payload['aud'] = "my_aud" + token = utils.jwt_encode_handler(payload) + decoded_payload = utils.jwt_decode_handler(token) + self.assertEqual(decoded_payload, payload) + + def tearDown(self): + api_settings.JWT_AUDIENCE = DEFAULTS['JWT_AUDIENCE'] + + +class TestIssuer(TestCase): + def setUp(self): + api_settings.JWT_ISSUER = "example.com" + + self.username = 'jpueblo' + self.email = 'jpueblo@example.com' + self.user = User.objects.create_user(self.username, self.email) + + return super(TestIssuer, self).setUp() + + def test_fail_issuer_missing(self): + payload = utils.jwt_payload_handler(self.user) + token = utils.jwt_encode_handler(payload) + with self.assertRaises(jwt.exceptions.InvalidIssuerError): + utils.jwt_decode_handler(token) + + def test_fail_issuer_wrong(self): + payload = utils.jwt_payload_handler(self.user) + token = utils.jwt_encode_handler(payload) + payload['iss'] = "example2.com" + with self.assertRaises(jwt.exceptions.InvalidIssuerError): + utils.jwt_decode_handler(token) + + def test_correct_issuer(self): + payload = utils.jwt_payload_handler(self.user) + payload['iss'] = "example.com" + token = utils.jwt_encode_handler(payload) + decoded_payload = utils.jwt_decode_handler(token) + self.assertEqual(decoded_payload, payload) + + def tearDown(self): + api_settings.JWT_ISSUER = DEFAULTS['JWT_ISSUER']