Serverless Authenticated Applications with Federated (Facebook, Google, Amazon logins)
Update 2020–08–07: I think doing this today, I’d just using https://aws.amazon.com/amplify/framework since they pretty much did all the hard parts you don’t want to do and offer it at a good price.
Original Post: My project partner, Travis Lee, and I have been working on building a website and we got started with a more traditional web server and realized we just didn’t want to have to deal with running it ourselves. We thought, why not try building it with AWS Lambda with API Gateway. Lambda lets you not worry about the server, it’s got monitoring, logging, traffic throttling, and traffic analysis built in. As we found it, it can also let you separate your authentication checking logic from your Lambda functions completely.
For our website, we wanted to allow users to login with various identity providers like Facebook or Google. The standard way this would go would be to have this login then create a user object in our database which we have to keep track of and to keep a session cookie on the user letting us know they are logged in. The user would then request resources from our server and our server would get those resources for the user.
Since our website logic was going to be in Lambda functions, it looked like it would be tedious to get the session cookie data into the Lambda function to see if we could process the request or not and mix that in with how we actually wanted to process the request. We thought, “What if we didn’t have to own any authentication?”
What if we didn’t have to own any authentication?
We found AWS Cognito (which wasn’t obvious what it does, but we’ll tell you) which lets us turn Facebook, Google, etc. app sessions into AWS sessions.
Why would I want AWS sessions?
With these AWS sessions we’re able to have our AWS API Gateway require privileged credentials to access those resources. Another side-benefit is that our clients can also use those credentials to make calls directly to other AWS services if we want them to cutting out our server as the middle man.
The architecture looks something like this borrowed image then. Imagine another arrow showing the client is able to place cats in a ‘sweet-cat-pics’ bucket.
There are a lot of blogs already with some parts of this, but I had trouble finding anything that was incorporating Cognito, API Gateway, Lambda, and Facebook logins with enough detail to be easy to follow. You can find my source at:
Prerequisites:
- AWS account
- Facebook account
Piece together from these various blogs:
- Create a Facebook app: https://developers.facebook.com/docs/apps/register
- Create Cognito Federated Identities and hook into your client: https://mobile.awsblog.com/post/TxBVEDL5Z8JKAC/Use-Amazon-Cognito-in-your-website-for-simple-AWS-authentication
- If building a website, serve client HTML from S3 secured by unauthenticated Cognito AWS role.
- Add Facebook Login to your Facebook in the Facebook App Hub by clicking “+ Add Product”. If building a website, configure “Valid OAuth redirect URIs”
- Understand how to create API Gateways and Lambda Functions: https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html
- Create secure API Gateways and Lambda Functions using Cognito with Swagger for the IDL: https://github.com/awslabs/api-gateway-secure-pet-store OR (my slightly modified version with a web example) https://github.com/myyk/api-gateway-secure-pet-store
- Use generated SDK for your API in your client.
If you followed all that you should have a new secure API available that clients can use with their Facebook credentials. It should be trivial to add new identity providers from the many supported by Cognito.
Possible Improvements
There is still a lot more clicking around to create all those resources than I generally find acceptable, but much of that is one time setup. If you’re going to use this for your development environment, you’d probably want to automate anything you’ll update a bunch:
- Setup Lambdas with CloudFormation: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html
- Setup API Gateway from Swagger: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html
Thanks
all the blogs, documentation, forums that helped me piece everything together, and to Travis Lee.