AWS Cognito for Django3 + DRF Authentication

dfranca

I'm trying to set up an AWS Cognito backend I have a React frontend already working with it, now I need my DRF API to authenticate using the Cognito as backend.

I have found a few Python packages for that, none of them seem to be actively maintained django-warrant doesn't work with Django3 and is pretty much dead

Django Cognito JWT seems to be my best bet, but also not actively maintained, the documentation is very poor, and there is a medium post on how to use, not very detailed, but better than nothing.

So, I tried to follow the documentation

Added the env vars on my settings

COGNITO_AWS_REGION = 'us-east-1'
COGNITO_USER_POOL = 'us-east-1_xxxxxxx'  # same user pool id I'm using on the React app
COGNITO_AUDIENCE = 'XXXXXXXXXXXXXXXXXXXXXX' # the same client id I'm using on the React app

Then on my DRF authentication classes:

    'DEFAULT_AUTHENTICATION_CLASSES': [
        'django_cognito_jwt.JSONWebTokenAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],

And finally the user model:

AUTH_USER_MODEL = 'accounts.MyUser'
COGNITO_USER_MODEL = "accounts.MyUser"

My custom User Model:

class MyUser(AbstractUser):
    """User model."""

    username = None
    email = models.EmailField(_('email address'), unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

I'm also using DRF JWT package, and if I try to login with a Cognito user, something like:

curl -X POST -H "Content-Type: application/json" -d '{"email":"[email protected]","password":"secretpassword"}' http://localhost/api-token-auth/

I get an error

{"non_field_errors":["Unable to log in with provided credentials."]}

On another hand, if I try to login with a local Django user via Django Rest Framework JWT it works fine and I get the JWT token as a response, so I guess the issue is the Cognito integration.

Any idea what I'm missing? or how can I debug in order to figure out what is happening?

UPDATE

After digging a bit more on the code, I found out a few things:

Even doing a DRF JWT authentication, the code end up at: django/contrib/auth/init.py Where it loops through all the authentication backends for Django, not for DRF:

for backend, backend_path in _get_backends(return_tuples=True):

Still using the ModelBackend to authenticate the user.

So, I guess I also need to add some Cognito authentication backend for Django. I checked if I could just use the same backend used on DRF, but then I got an error of invalid argument: TypeError: authenticate() got an unexpected keyword argument 'email'

UPDATE 2 It seems that one of the issues is because I use email instead of username to authenticate, and none of the packages seems to support it

Saiful Azad

Basically, there are 2 steps to achieve your goal.

  1. Get IdToken and AccessToken from Cognito by Boto3 library.
  2. Apply the IdToken in this Pattern Authorization Bearer IdToken to call API via curl.

Unlike rest_framework_jwt , django_cognito_jwt only deals with JWT token at header. django_cognito_jwt does not cover step 1. That is why you are getting this error TypeError: authenticate() got an unexpected keyword argument 'email'.

So, solution is use boto3 to get IdToken and apply curl by passing Authorization:Bearer IdToken header.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Authentication with Lambda and AWS Cognito

AWS Cognito Authentication in Reactjs

AWS Cognito HTTP authentication

AWS Cognito User Authentication

AWS Cognito as Django authentication back-end for web site

Firebase authentication vs AWS Cognito

AWS Cognito authentication with Bearer token

Integrating AWS Cognito with API for authentication

How do AWS Cognito Authentication tokens refresh

AWS API gateway authentication without using Cognito

How to ignore MFA Authentication in AWS Cognito

Object is of type unknown with AWS Cognito authentication

AWS Cognito Amplify Authentication and Angular UI Components

React Native authentication and Subscribtion with AWS Cognito UserPools

AWS Cognito API Authentication flow SDKs

Custom Authentication flow with aws amplify cognito

How to achieve certificate based authentication with AWS Cognito?

AWS iOS SDK Cognito Developer Authentication (Swift)

AWS Cognito error: Authentication delegate not set

Multi-Tenant Authentication with AWS Cognito

ios swift AWS cognito and Facebook Authentication

AWS Cognito Pre authentication get user data

how to use AWS cognito with custom authentication to create temporary s3 upload security token

Checking if email is verified in aws cognito using AWS Amplify Authentication module

Django, jwt authentication in django view, not just DRF

How to include TOTP MFA in AWS Cognito authentication process

Authentication/Cognito SDK not working once deployed to AWS Lambda

Better User authentication?(aws cognito or Oauth2 or okta)

Google Authentication fails with AWS Cognito Identity Pool on Android