Skip to content

Commit a6756b6

Browse files
committed
Split the get_or_create_for_cognito method.
Split the method into get_user and create_for_cognito. Spliting the method into two allows more efficient calling of the method, especially when using access token. The get_user method will first check whether the user exists. If exists, it will directly skip the get requests from UserInfo endpoint, and also skip the attempt for user creation, and directly return the user object. The UserInfo endpoint will be only called during the initial registeration of the client that does not exist in User database.
1 parent ed5866f commit a6756b6

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

README.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,43 @@ You need to specify the Cognito domain in the ``settings.py`` file to obtain the
8686
.. code-block:: python
8787
8888
COGNITO_DOMAIN = "your-user-pool-domain" # eg, exampledomain.auth.ap-southeast-1.amazoncognito.com
89+
90+
To use the backend functions, at the DJANGO_USER_MODEL, could define methods as follows:
91+
92+
.. code-block:: python
93+
94+
class CustomizedUserManager(UserManager):
95+
def get_user(self, payload):
96+
cognito_id = payload['sub']
97+
try:
98+
return self.get(cognito_id=cognito_id)
99+
except self.model.DoesNotExist:
100+
return None
101+
102+
def create_for_cognito(self, payload):
103+
"""Get any value from `payload` here
104+
ipdb> pprint(payload)
105+
{'aud': '159ufjrihgehb67sn373aotli7',
106+
'auth_time': 1583503962,
107+
'cognito:username': 'john-rambo',
108+
'email': '[email protected]',
109+
'email_verified': True,
110+
'event_id': 'd92a99c2-c49e-4312-8a57-c0dccb84f1c3',
111+
'exp': 1583507562,
112+
'iat': 1583503962,
113+
'iss': 'https://cognito-idp.us-west-2.amazonaws.com/us-west-2_flCJaoDig',
114+
'sub': '2e4790a0-35a4-45d7-b10c-ced79be22e94',
115+
'token_use': 'id'}
116+
"""
117+
cognito_id = payload['sub']
118+
119+
try:
120+
user = self.create(
121+
username= payload["cognito:username"] if payload.get("cognito:username") else payload["username"],
122+
cognito_id=cognito_id,
123+
email=payload['email'],
124+
is_active=True)
125+
except IntegrityError:
126+
user = self.get(cognito_id=cognito_id)
127+
128+
return user

src/django_cognito_jwt/backend.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,17 @@ def authenticate(self, request):
3131
raise exceptions.AuthenticationFailed()
3232

3333
USER_MODEL = self.get_user_model()
34-
if settings.COGNITO_TOKEN_TYPE == "access":
35-
user_info = self.get_user_info(jwt_token.decode("UTF-8"))
36-
user_info = json.loads(user_info.decode("UTF-8"))
37-
user = USER_MODEL.objects.get_or_create_for_cognito(user_info)
38-
else:
39-
user = USER_MODEL.objects.get_or_create_for_cognito(jwt_payload)
34+
user = USER_MODEL.objects.get_user(jwt_payload)
35+
if not user:
36+
# Create new user if not exists
37+
payload = jwt_payload
38+
if settings.COGNITO_TOKEN_TYPE == "access":
39+
user_info = self.get_user_info(jwt_token.decode("UTF-8"))
40+
user_info = json.loads(user_info.decode("UTF-8"))
41+
payload = user_info
42+
43+
user = USER_MODEL.objects.create_for_cognito(payload)
44+
4045
return (user, jwt_token)
4146

4247
def get_user_model(self):

0 commit comments

Comments
 (0)