Just a general question about how this works in AWS. I didn't find the solution explained anywhere straight to the point.
I have a frontend hosted over cloudfront at one url and an AWS Appsync graphql api for the backend which exposes a seperate public url. The graphql api is managed by AWS Amplify the cloudfront distribution separately, in case it matters.
Now i am wondering how it is possible that the frontend can just call the appsync api? Shouldn't the CORS block access to the graphql api since they are on two different urls? Where is the magic happening?
Am I able to define a pre-generated api gateway url for my serverless application?
Currently there are two applications already made that has their own that was generated with cloud formation. The new application is using the serverless framework.
The client asked that I reuse the one that was generated for the other two applications on mine to extend the amount of endpoints over having its own url.
It’s not a custom url that uses a cname just a straight generated api gateway one they would like me to piggy back off of.
Sadly you can't do that with AWS-provided URLs. The only way to join several APIs under a single URL domain is to use custom domains. Then you can hook up multiple APIs to one domain, e.g. api.mydomain.org, api2.mydomain.org.
I'm new to AWS and just exploring possible architectures using the tools like AWS cognito, AWS Cloudfront, and/or AWS API Gateway.
Currently, my app is deployed in an EC2 instance and here is the outline:
Frontend: React app running on port 80. When a user goes to https://myapp.com, the request is be directed to my-ec2-instance:80.
Backend: Nodejs + Express running on port 3000. After the user loads the frontend in the browser, when he interacts with the website, http requests are sent to https://myapp.com/api/*, which are routed to my-ec2-instance:3000;
I use nginx/openresty as a single entry point to my webapp, and it does authorization with AWS Cognito, and then reverse-proxy the requests based on path:
Now, instead of managing an EC2 instance with the nginx/openresty service in it, I want to go serverless.
I plan to point my domain myapp.com to AWS CloudFront, and then Cloudfront acts as the single entry point to replace the functionalities of Nginx/Openresty. It should do the following:
Authorization with AWS Cognito:
When a user first visits myapp.com, he is directed to AWS Cognito from AWS Cloudfront to complete the sign-in step.
path-based reverse proxy: I know this can be done. I can configure this from the CloudFront configuration page.
But for 1, Can Cloudfront do authorization with AWS Cognito? Is this the right way of using AWS Cloudfront?
After reading the AWS doc and trying with Cloudfront configurations, I started to think that Cloudfront is not build for such a use case at all.
Any suggestions?
You mentioned "serverless", but using ec2 which is a server. You can use AWS lambda (Node JS) for backend and S3 for front-end. AWS API gateway has built in authorization feature where you can use AWS Cognito. Cloudfront is for content delivery cached in edge locations to deliver content faster from nearest edge locations where the user is located.
You can follow the below steps to implement serverless concept in AWS.
Create the front end and upload to S3
Configure AWS Cognito and grab the following
UserPoolId: 'xxxx',
ClientId: 'xxxx',
IdentityPoolId: 'xxxx',
Region: 'xxxx'
Use aws-cognito-sdk.min.js to authenticate user and get the JWT token, sample code can be found here. This JWT token needs to be passed to each and every API call in the header section. If using AJAX then sample code is
var xhr = new XMLHttpRequest();
xhr.setRequestHeader("Authorization", idToken);
Configure AWS API gateway and cloudfront - follow documentation
In API Gateway configuration select Cognito for those API's for which you want to use authorized access.
Create AWS Lambda functions for the backend and link to API Gateway.
PROBLEMS
It feels like your current problems are:
Requests to Cloudfront will require a cookie, and Cloudfront has only very limited capabilities for running code to verify them (via lambda edge extensions)
It does not make sense to put a reverse proxy in front of Cloudfront, since it should deploy web resources to 20 or so global locations for you
SOLUTION APPROACH
If you can separate web and API concerns you can solve your problem:
Make your Express web back end (used during local development) serve only static content
Use the reverse proxy and cookies only for API and OAuth requests
TOKEN HANDLER PATTERN
At Curity we have put together some related resources, illustrated in the following picture:
It is a tricky flow from a deployment viewpoint, though the idea is to just plug in the token handler components, so that your SPA and APIs require only simple code, while also using the best security.
AWS CODE EXAMPLE
Out of interest a React sample of mine uses this pattern with Cognito, and is deployed to Cloudfront.
Few ideas.
Frontend:
Use S3 + CloudFront distribution.
About the authentication, you can try using a Lambda function "linked" to the CloudFront distribution, redirecting to Cognito.
Backend:
Deploy on Fargate, EC2 or do you prefer.
Put an Application Load Balancer (ALB) in front of the endpoint, so you can define rules with redirects, forward, deny, etc.
I need some advise in one of my use case. I have a website which is based on html, css, javascript. Also there is a form present in the website into which user fill the details and submit the form. The details were getting submitted onto some 3rd party Database. Hence i need to deploy the website using serverless method. As per my understanding i could use s3 to host the static website. But as in my use case there is a form which intereact with DB and its a dynamic functionality so what could be the best approach to deploy the website as serverless if i uses the combination of Lambda,Api Gateway,S3 etc.Please guide.
I would recommend having look at this official AWS tutorial:
Build a Serverless Web Application
It uses DynamoDb instead a third party database, but its architecture would be roughly same.
Thus, you would host your static content with the html form on S3. The form would be submitted to an API Gateway endpoint that you will have to create.
The API gateway endpoint would integrate with a lambda function. The function would be responsible for reading or writing into your third party database.
So the workflow, would be like in the tutorial mantioned:
client -> S3 website with form -> API gateweay -> lambda -> third party db
For more details about how to architect serverless apps on AWS, I would also recommend the excellent AWS white paper:
AWS Serverless Multi-Tier Architectures With Amazon API Gateway and AWS Lambda
Host the static website in S3 & call the DB API directly from frontend JS!
Title says it all: is it possible to host a static-generated site on S3 and restrict access to it based on Github OAuth?
Scenario: You generate a static site (using Hugo or whatever) and you upload it to S3 as a static site. Is there some combination of AWS services (API Gateway, Lambda, etc.) that can make it so that only members of my Github organization can access this site? Authenticating with Github's OAuth? Anyone not authenticated should be treated with a 404.
Has anyone done this or know how to do it? Is such a thing possible without running a backing server (EC2, Heroku, DigitalOcean Droplet, etc.) of some kind?
Looking for a complete answer that outlines steps on how to set this up (if possible) with the lowest cost/complexity.
Yes this is possible. I've followed this tutorial in the past to secure a static site on S3 behind an Auth0 authentication, using DynamoDB as the user account store, and API Gateway + AWS Lambda as the authentication service. That was an AngularJS SPA, but the general concept should be the same.
Github is listed as an Auth0 identity provider. I would recommend looking at this documentation for using Auth0 on your site. Once you get it working you would have to configure your static site generator to include the authentication JavaScript code on every page it generates.