AWS Cognito, the good the bad the ugly and CDK
Alrighty, I've been using AWS Cognito for a while now and thought it was time for a write up. We'll run through a quick overview and highlight the good and bad, there is also a CDK example provided in the talkncloud github repo.
What the heck is AWS Cognito?
Cognito is a managed authentication and authorization service, commonly used to provide sign up, sign in and access control for web and mobile apps. If you've looked at AWS Amplify, its the authentication service in that.
Some standout features:
- Standalone directory
- Federated directory with support for Google, Apple, Amazon, Facebook and SAML
- oAuth and OpenID
- Bunch of compliance HIPPA, SoC etc
- Provide access to AWS resources
If you're an enterprise you might use cognito to federate to Azure AD so that your web apps or mobile apps authenticate with your existing user base.
These are IAM users, this is totally separate, providing Cognito access doesn't give someone console access or anything like that.
As the title of the post may have eluded to, there are some really cool bits about cognito. I'm going to run through those.
Cognito has everything you'd want in a basic service. The standalone directory allows users to signup to create an account in your cognito pool and with that comes the usuals like:
- password complexity
- email notifications
- password reset
- user attributes like phone, name, address and custom
- basic admin like enable, disable, delete etc
A single pool and have multiple clients, this is cool. So you use the one pool and create different requirements. You may need to create an app client for a mobile with redirects inside the app e.g. myapp://signin and another for the web e.g. https://cup.talkncloud.com/signin. The same goes for different federated directories for each.
The hosted UI offloads the requirement to build out the sign, signup, reset etc screen to cognito. They provide everything you need when you use this feature. When you create your directory you get a unique endpoint url, this forms part of the hosted UI. When you click the hosted UI from within the console it will launch the login screen and everything that you've configured e.g. directory etc should work.
As above, you get a unique endpoint url and with that comes customization using Route53. You just end up with an alias record pointing to the cognito resource, it's pretty straight forward.
Who doesn't like federated identities? Pretty sure we all do, this gives users access to their existing accounts with providers like Google and Facebook. It's very easy to do, you simply register the app with the provider and exchange information inside the pool. The same goes for Azure AD, you create a new enterprise app and provide the meta url.
You can do some attribute mapping, this is useful for information like firstname, lastname etc. This means it will be available in the users attributes inside cognito which means you can access in your app via the ID or AccessToken.
If anyone is chasing more info on federated access with cognito, reach out and i'll do a more detailed write up.
AWS resource access
Sometimes you want to give users access to resources inside AWS via your app, this might be for integration with AWS AppSync, S3 or DynamoDB for example. Cognito provides the ability to securely provide that access for authenticated users.
AWS do a good job at getting you up and running quickly, they provide libraries for popular development frameworks like iOS, React and Vue. If you're familiar with VueJS you can use components to load cognito in your app with default screens and little work. If you're looking for anything but standard it gets a bit hairy.
It's bloody cheap
This thing scales into the millions and it's pretty cheap if you use the standalone directory, things start getting more expensive once you add federated users but nothing crazy.
- 50k standard alone users, free, $0.0055 per user afer that
- 50 federated users free, $0.015 per user after that
There are more tiers after that, but you get the idea, more pricing can be found at AWS.
Always, always, always check the pricing so you know what you're up for, it's part of the well-architected framework and just make sense.
If you've ever used Cognito you know what i'm talking about. There are a few moments of rage that you've probably experienced during the configuration and integration phase.
You can select user attributes that are required, this might be useful if you need like a name or something. Once set it cannot be changed. If you create a custom attribute you can use it but it can't be removed after that. You'll need to recreate the pool...
The username can be made case insensitive, I have no idea why this isn't the default option or why it's even an option. But, if you forget to enable this you'll end up with users like MyEmail@talkncloud.com and email@example.com as two different users. It's nuts! to enable this after the pool as been created you'll need to recreate the pool...
You hear mixed reviews on AWS documentation, I think it's not too bad, this is more one of the cases where it's lacking. It can be tricky to navigate Cognito as a new comer, you will likely recreate your pools many times. If you're using CDK or CloudFormation you will come across undocumented specials and cli only options, which isn't great.
Not related but worth a mention
If you run at cognito guns blazing and want to enable all of the federated identities like Google, Facebook, Apple etc. Just be aware you can't enable Apple without a developer account, which is paid. This isn't an AWS thing, it's Apple, just something to think about. If you're using Cognito for an Apple app it's likely not an issue.
You may have noticed a repeating theme when I was discussing "the bad", you may have guessed it. Recreating pools.
If you stuff up certain settings during creation of the pool the only way to fix these itmes is to recreate the pool. Yes, thats right. You need to recreate the pool. Now, if you've already created the pool and you have say 5k of users that might not be ideal.
Be mindful of the following settings:
- Required attributes
- Case sensitivity
- User name attribute
There may be others, but for now, settle on these ones.
Note: You can create, delete, configure as many app clients as needed without having to redo the pool.
Stop talking, gimme CDK
I've put together a working example of AWS Cognito for everything you need to get up and running quickly in CDK. This also includes federation for Google, Facebook and Amazon but just need you'll need to setup your external identity providers like Google etc and swap out with your ID's and secrets.
The project is available open-source on github:
Once you've started using Cognito in your apps a few times you get the hang of it. The usual token handling in apps etc is everything you'd expect and the work AWS with frameworks really does cut down on dev time. It's worth a go if you're already in AWS and using other services.
If you are using something else, let me know, i'd be keen to hear from others on what works for them.