Authentication and authorization is hard. Implementing a custom solution is error prone and usually a big effort. Nowadays you can buy almost anything as a service and that includes authentication and user management. AWS Cognito promises to provide a complete solution to user and identity management. We decided to use Cognito in a real customer project and found out that it fulfills this promise. However we had some challenges understanding the concepts and putting it all together.
“Amazon Cognito makes it easy for you to have users sign up and sign in to your apps, federate identities from social identity providers, secure access to AWS resources and synchronize data across multiple devices, platforms, and applications.”
Ok, sounds great! However in our case we didn’t care so much about the sync features.
“Cognito Identity is fully managed and can scale to support hundreds of millions of users.”
OMG this is what we really want! Take my money immediately.
“User Pool feature has a free tier of 50,000 MAUs. The free tier does not automatically expire at the end of your 12 month AWS Free Tier term, and it is available to both existing and new AWS customers indefinitely.” (MAU = Monthly Active User)
So you don’t even want money until we have +50K users. Fine!
Before finding Cognito we implemented our first proto using Auth0 which provides similar features and apparently had better Google visibility. Auth0 did actually work very well and documentation was good. However when we realised that AWS provides similar functionalities (with lower prices) we pretty soon decided to switch to Cognito.
We were going to use JWT tokens with our backend API’s and it was pretty clear what needed to be done. We found out that Cognito supports JWT tokens (access, id, refresh) in OAuth2 fashion. AWS provides step-by-step instructions for verifying the tokens but sadly there’s no ready-to-use utilities or code examples provided. However we didn’t have too much trouble implementing token verification into our backend.
At this point we learned that in Cognito you create user pools which can function as both user directory and identity provider. The pool allows users to register with email, phone number or username. You can also decide to store other data about the users into your pool and you can define the fields yourself. This data can also be included into JWT-token payload. We ended up creating 3 user pools, one for each role in our apps. In the API backend we check from which pool the token was issued from and perform authorization accordingly.
We also experimented Cognitos ability to grant direct access to AWS resources. Under the hood Cognito can issue temporary AWS IAM credentials in exhange for id-token. We were hoping to use for example AWS CloudSearch directly from the Angular2 apps. We couldn’t get the token –> IAM –> SDK –> CloudSearch chain to work in practice. After 2 days of trial and error with IAM, Cognito and CloudSearch we gave up and decided to make one of our backend API’s to deal with access control policy and do the request to CloudSearch. We found it easier and faster to implement this way.
AWS Cognito does what it promises but immaturity of tech examples may cause some gray hairs with the browser SDK. I feel much more safe using Cognito instead of bringing up our own auth & user management solution. We focused on the most basic flows but Cognito offers a lot more. This article didn’t cover the data sync features at all since we didn’t really use them. Cognito also offers other interesting features like federated SAML identities and customizing registration and login flows with AWS Lambda functions.
Authentication and authorization is still hard. Cognito offers tons of possibilities and promises to scale to hundreds of millions of users. We have been very satisfied with the features and customisability but there’s room for improvement in developer experience. You may have to prepare for at least some kind of learning curve even with the basic scenarios. Also the immaturity of examples may cause some confusion. I would recommend Cognito as a no-brainer solution for authentication and authorization if you’re building your own stuff around AWS services. There are also alternatives like Azure AD and Auth0.
One of the most interesting features in Cognito is that it enables creating truly Serverless Single Page Web Apps on top of out-of-box AWS services by granting direct access to AWS-resources. For example it’s totally doable to hook a web app directly to DynamoDB or S3 and define fine-grained access policies with IAM. This way it’s possible to get rid of custom backend tier and have the Backend as a Service (BaaS) instead. The app running in browser would contain the glue and business logic to pull it all together. I’m not saying it would be simple though, especially compared to platforms that have been focusing to this kind of approach for a while like Firebase. In practice we experienced using AWS services directly a bit too time consuming and difficult to implement for our start-up case. But it’s definitely interesting to see how AWS SDK’s targeted for browsers develop in the near future.
You can read more about the subject from these references: