djangopythonsecurityaws

Introducing Django Cognito JWT for Django REST Framework

3 min read

Introducing Django Cognito JWT for Django REST Framework

--

Last August, AWS has introduced OAuth2 support for Cognito, their login & sign-up service that you can use to build your user account infrastructure with. Support for issuing JSON Web Tokens (JWT) and leveraging JSON Web Keys (JWK) is included in this.

When using OAuth2.0 for authentication and authorisation, you can use this for authenticating your API’s with individual user’s credentials: the user-specific Access Token. This enables a lot of possibilities when building distributed, personalised systems in an elegant and, more importantly, secure way. You can see it as an individual API key for a user, that is continuously refreshed.

Prior to JWT those tokens were just ‘hashes’ that could be verified by the consuming system. Quite usable for just authentication, but that’s all it did. With JWT, you can encode information within the tokens as a JSON object. This offers opportunities for additional security, but also to add information about the user such as the user ID.

This last fact makes the use of JWT quite powerful, as the consuming system can now ‘know’ which user made the request, without having to ask this to another system. This makes it a lot easier to personalise an experience or store data for an individual user.

We have been using JWT with other systems (Auth0 has support, for example) in the past, and have used it to authenticate API’s, given the elegant nature of the tokens.

Now that AWS introduced JWT support in Cognito, we immediately looked into it for a new project of ours: a React Native app including a login.

AWS Amplify

For building the front-end of the app we have selected the aws-amplify library for implementing AWS Cognito in React Native, including support for OAuth2/JWT.

AWS Amplify is aimed at “interacting with cloud services that use JavaScript applications”, offering JavaScript support for a range of AWS ‘mobile’ services, such as Cognito, Mobile Analytics and S3 storage. It is built on top of the official AWS SDK for JavaScript.

The library is quite young and that’s noticeable; we spent the first couple of days debugging some issues with Cognito. But the AWS team is iterating quite fast, with a new release every week. So for now we feel the bet on AWS Amplify will be successful.

django-cognito-jwt

We build most of our back-ends in Django and when we build API’s, we generally use django-rest-framework. It is simply the most mature and versatile REST option in the Django space.

A good authentication back-end for Cognito/JWT was lacking, so we decided to create it.

To use it, install the library via pip, and then simply add your Cognito settings and configure REST Framework to authenticate against it:

COGNITO_AWS_REGION = '<aws region>' # 'eu-central-1'COGNITO_USER_POOL = '<user pool>' # 'eu-central-1_xYzaq'COGNITO_AUDIENCE = '<client id>'REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ ... 'django_cognito_jwt.JSONWebTokenAuthentication', ... ], ...}

You can find our module in the usual place:

Tags used in this article:
djangopythonsecurityaws