Managing users and API keys is a necessary task for creating a Software as a Service (SaaS). In this article, I demonstrate how to create a simple, cost effective serverless SaaS user management application. The frontend is created using Vue JS and the Amplify plugin. The backend uses Cognito for authentication of the user management API, and a key system created with DynamoDB which authorises users to access a test API created with Application Load Balancer. Check out the live demo 💽.
Not everything is intended for everyone. In a scenario where restricting access is necessary, user management must become a component of the architecture. The AWS solution to user management is the Cognito service. This integrates simply with API Gateway — but as described in the previous article, API gateway can get pretty expensive, and for high load the more cost effective alternative is Application Load Balancer.
Cheaper than API Gateway — ALB with Lambda using CloudFormation
An alternative to API gateway is Application Load Balancer. ALB can be connected with Lambda to produce a highly…
The architecture for this user management application (see below) makes use of both API gateway and ALB for their respective benefits. API gateway is chosen for the User API for two reasons:
- the requests are likely to be low in volume meaning costs will be low
- the requests are direct from the frontend with authentication using the Amplify package with the Vue JS framework
ALB is chosen for the example service Test API as it is expected to experience a high volume of requests which might rack up a hefty bill on API Gateway. Also, the requests are likely to be from other servers meaning API keys are preferable. Users are generated an API key on sign up which is used to authenticate the Test API. Usage of the API is monitored by incrementing a count on the User table each time a request is made to the Test API.
This architecture is cost effective for high-load APIs. A quote from this article might help you decide if your service falls into that category:
$15 (ALB’s cost) worth of API Gateway calls will net you around 4.3 million API calls in the month (well, 5.3 million if you count the free tier). So, if your API is small enough to fit under that number of calls, stick with API Gateway — it’s simpler to use. But, 5.3 million API calls is only around two requests per second. So, if your API is used very much at all — or even if you have DNS health checks enabled — you could easily end up paying more for API Gateway than you would for Application Load Balancer.
I presume this article will not bring in more than two reads per second, meaning an ALB would not be suitable for running the demo of the service. Instead, the test API seen in the diagram has been replaced with another API Gateway. You can see a demonstration of the app in use below.
Let’s Build! 🔩
The infrastructure for this system is written as code using the CloudFormation framework.
ALBs must be placed within a Virtual Private Cloud on AWS. The service uses a stripped down VPC consisting of only two public subnets and an Internet Gateway. A more complete VPC is described in a previous article:
Virtual Private Cloud on AWS — Quickstart with CloudFormation
A Virtual Private Cloud is the foundation from which to build a new system. In this article, I demonstrate how to…
User Management with Cognito
The AWS Cognito service is used to manage users. Users are stored in user pools, and Clients (mobile or web apps) can interact with them using an API. I configured the Cognito user pool to send an email with a verification code on sign up.
You must also define a client; this allows for OAuth on our frontend client.
NB: Setting the URLs to
localhostallows for local development.
Cognito user pools offer useful event tiggers such as sign up confirmation. I have used the
post-confirmation event to trigger a Lambda function which writes the user’s username, a newly generated API key, and a zero initialised counter to a DynamoDB table. The table has a Global Secondary Index (GSI) on the
Key attribute which allows for a user lookup with just the
PostConfirmation Lambda function template:
PostConfirmation Lambda is a Python function which creates an API key and stores it in the DynamoDB table:
Endpoints created for users to access their profile and generate an API key are authenticated for the logged in user. Authentication is easily added to API gateway with Cognito (CORS are set open for development purposes).
The code for getting and generating keys is very similar to the post-confirmation Lambda code.
Service API — Test
The API I’ve created with ALB is for the high traffic volume endpoints which are authenticated using an API key. This API key is sent in a POST request to the service.
The service uses the user’s API key for a query on a GSI of the user table to get the
Count, then increment the
Count and return the updated
Count. Again, I have added open CORS whilst developing. For security, these should been locked down.
vue create frontend
---step through configurations and use defaults
vue add vuetify
AWS Amplify is a JS plugin which consists of some useful functions for serverless Auth and API, as well as some frontend components for Vue JS, enabling user authentication flows.
In the Vue App, I use Amplify’s Authenticator UI components for user authentication flows.
This is what an authenticated user sees:
With the API configured in
main.js, calling an API inside a Vue component is pretty simple.
The authorisation header is set for the current logged in user. The code for accessing the User API is just as clean.
Using CloudFormation templates mean it is simple to deploy this infrastructure using the AWS CLI.
aws cloudformation deploy --template-name ./00-infra.yml
Vue JS builds a static site which is uploaded to S3 and deployed using CloudFront.
npm run build;
aws s3 cp ./dist s3://<< your bucket name >> --recursive
This Architecture is the basis for a SaaS, the next step is to link to a payment service such as Stripe to handle subscriptions, which is done in part 2:
💸 Pay Me: Quickstart for creating a SaaS pt.2 — Stripe Payments
Creating a SaaS solution is fun, but creating a payment system can be a minefield. In this article, I demonstrate how…
Some popular APIs from Rapid API Top 100:
Thanks for reading