Skip to content

Commit

Permalink
Split the get_or_create_for_cognito method into get_user and create_f…
Browse files Browse the repository at this point in the history
…or_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.
  • Loading branch information
ckng0221 committed Feb 26, 2023
1 parent ed5866f commit deada1a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
39 changes: 39 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,42 @@ You need to specify the Cognito domain in the ``settings.py`` file to obtain the
.. code-block:: python
COGNITO_DOMAIN = "your-user-pool-domain" # eg, exampledomain.auth.ap-southeast-1.amazoncognito.com
To use the backend functions, at the DJANGO_USER_MODEL, could define methods as follows:

.. code-block:: python
class CustomizedUserManager(UserManager):
def get_user(self, payload):
cognito_id = payload['sub']
try:
return self.get(cognito_id=cognito_id)
except self.model.DoesNotExist:
return None

def create_for_cognito(self, payload):
"""Get any value from `payload` here
ipdb> pprint(payload)
{'aud': '159ufjrihgehb67sn373aotli7',
'auth_time': 1583503962,
'cognito:username': 'john-rambo',
'email': '[email protected]',
'email_verified': True,
'event_id': 'd92a99c2-c49e-4312-8a57-c0dccb84f1c3',
'exp': 1583507562,
'iat': 1583503962,
'iss': 'https://cognito-idp.us-west-2.amazonaws.com/us-west-2_flCJaoDig',
'sub': '2e4790a0-35a4-45d7-b10c-ced79be22e94',
'token_use': 'id'}
"""
cognito_id = payload['sub']

try:
user = self.create(
username= payload["cognito:username"] if payload.get("cognito:username") else payload["username"],
cognito_id=cognito_id,
email=payload['email'],
is_active=True)
except IntegrityError:
user = self.get(cognito_id=cognito_id)

return user
17 changes: 11 additions & 6 deletions src/django_cognito_jwt/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ def authenticate(self, request):
raise exceptions.AuthenticationFailed()

USER_MODEL = self.get_user_model()
if settings.COGNITO_TOKEN_TYPE == "access":
user_info = self.get_user_info(jwt_token.decode("UTF-8"))
user_info = json.loads(user_info.decode("UTF-8"))
user = USER_MODEL.objects.get_or_create_for_cognito(user_info)
else:
user = USER_MODEL.objects.get_or_create_for_cognito(jwt_payload)
user = USER_MODEL.objects.get_user(jwt_payload)
if not user:
# Create new user if not exists
payload = jwt_payload
if settings.COGNITO_TOKEN_TYPE == "access":
user_info = self.get_user_info(jwt_token.decode("UTF-8"))
user_info = json.loads(user_info.decode("UTF-8"))
payload = user_info

user = USER_MODEL.objects.create_for_cognito(payload)

return (user, jwt_token)

def get_user_model(self):
Expand Down

0 comments on commit deada1a

Please sign in to comment.