Cognito authentication¶
What is it¶
Cognito is a single sign-on system from AWS. It allows multiple apps to accept authentication from the same set of user accounts. It separates the management of users and permissions from the applications that use them.
Why we use cognito¶
We're invested in AWS, so we might as well use this too.
How we implement it¶
We're following the implementation from the djangostar tutorial.
These are the steps involved:
- Backend downloads JWKS from Cognito User Pool on launch
- User submits credentials and gets id_token and access_token
- User sends request with token
- Backend verifies token and processes request
- User gets response from authenticated API
sequenceDiagram
autonumber
participant Cognito User Pool
participant Backend
participant User
Backend->>+Cognito User Pool: getJWKS()
Cognito User Pool-->>-Backend: JWKS
User->>+Cognito User Pool: login(user, pass)
Cognito User Pool-->>-User: id_token, access_token
User->>+Backend:get(request, access_token)
Backend->>Backend: Verify token against JWKS and process request
Backend-->>-User:response from authenticated API
Current Dev Setup¶
- Created app client called "backend within the vrms-dev user pool, with ALLOW_ADMIN_USER_PASSWORD_AUTH enabled
- "Domain Name" is already created at https://hackforla-vrms-dev.auth.us-west-2.amazoncognito.com
- In "App client settings", enabled Implicit grant and openid, Callback URL http://localhost:8000/admin
How it works now with the dev user pool and local development backend¶
- Create a cognito user and login from the Hosted UI (from App client settings). Successful login will redirect to localhost:8000/admin with the necessary tokens
- Take the access_token from the URL and make a GET request to http://localhost:8000/api/v1/me (Headers key=Authorization, value=Bearer
) - Backend should return the user's profile data
Authentication Guide for Cognito¶
Before following the below instruction, please ensure you have docker up and running and the build-image running, you can run it with the command ./scripts/buildrun.sh
.
- Login (or register first then login) to a cognito account here. Do not worry if you see error messages - you will be using the url to authenticate.
- Copy the URL when it redirects, and now in the new tab open the online tool.
- You will notice
^.*access_token=(.*)&expires_in.*$
this is the regex used to extract the access_tokens.- Clear the top box and paste the URL text into it. Make sure you have
Replace
selected and$1
in the bottom box, The upper box should show there's 1 match. - The bottom box's content is the extracted
access_token
.
- Clear the top box and paste the URL text into it. Make sure you have
- Open ModHeader(for best results we recommend using Google Chrome).
- If the icon is hidden,
click on the Puzzle icon in the upper right of the browser to see it
. - Select
Authorization
then type the wordBearer
and paste the token into ModHeader, it should follow the format:Authorization: Bearer <access_token>
.
- If the icon is hidden,
- To make sure that you are correctly authorized, you can go to the following api-interfaces.
- Local hosted DjangoRestFramework
- Explore APIs using local hosted Swagger
- A local hosted redoc ui is also available
Notes¶
The tutorial is 2 years old now (from 2020) and there's been some change made since then.
- We created an app client in Cognito for the backend to interface with. ALLOW_ADMIN_USER_PASSWORD_AUTH is the new name for the old ADMIN_NO_SRP_AUTH setting. Reference
- In the custom User model step, the ugettext-lazy package is gettext-lazy for Django 4.0 Reference
- The tutorial steps don't include instructions to test each step, so it's a little bit of following blindly with the help of linters until the last step.