Added documentation for setting CNAME record for lambda

This commit is contained in:
Khalim Conn-Kowlessar 2023-07-18 10:56:21 +01:00
parent 1c9a9ec88c
commit ea0e7a35ab
2 changed files with 93 additions and 37 deletions

View file

@ -1,14 +1,17 @@
# Backend
This is the api service that will supply the frontend with the insights that are driven by the machine
learning and data modelling services.
# Usage
## Prerequisites
Python 3.8+
Poetry for managing project dependencies and virtual environment.
## Installation and setup
1. Clone this directory and navigate into the project directory.
```commandline
@ -17,7 +20,7 @@ cd backend
```
2. For environment management, I'm using conda with pycharm which is a convenient setup for development
on a mac M1 however using tools such as poetry or pipenv is also fine.
on a mac M1 however using tools such as poetry or pipenv is also fine.
For example, to install conda and create a virtual environment for this project, run the following commands:
@ -33,6 +36,7 @@ conda install --file requirements/base.txt
```
3. Duplicate .env.example and rename it to .env
```commandline
cp .env.example .env
```
@ -41,7 +45,7 @@ cp .env.example .env
## Running the Application
from within the application you can run with the following command:
from within the application you can run with the following command:
```commandline
uvicorn app.main:app --reload
@ -51,11 +55,12 @@ You application will be available at the designated url
## API Documentation
FastAPI automatically generates interactive API documentation for your application. To access the docs, start your
FastAPI automatically generates interactive API documentation for your application. To access the docs, start your
server and visit <yourlocalurl>/docs in your browser. Alternatively, you can go to
<yourlocalurl>/redoc to view the documentation in the ReDoc format.
## Testing
To run tests, run the following command from the root of the project directory:
```commandline
@ -63,21 +68,22 @@ pytest
```
## Local Development
During local development, you may need to generate and use a dummy JWT to
During local development, you may need to generate and use a dummy JWT to
test protected endpoints of the application.
# Generating a Dummy JWT
FastAPI provides a convenient way to generate a dummy JWT for testing.
FastAPI provides a convenient way to generate a dummy JWT for testing.
To generate a dummy JWT, follow the steps below:
Make sure your application is running in a local environment.
Make sure your application is running in a local environment.
The dummy token endpoint is only available in a local environment.
While your application is running, visit the /dummy-token endpoint using a tool
While your application is running, visit the /dummy-token endpoint using a tool
like curl or any HTTP client like Postman.
For instance, if your server is running locally on port 8000, you can use curl
For instance, if your server is running locally on port 8000, you can use curl
to get a dummy token:
```commandline
@ -88,26 +94,30 @@ You will receive a response containing the dummy JWT
```json
{
"dummy_token": "<Your Dummy Token>"
"dummy_token": "<Your Dummy Token>"
}
```
### Using the Dummy JWT
Once you've obtained a dummy JWT, you can use it to make requests to
Once you've obtained a dummy JWT, you can use it to make requests to
protected endpoints in your application:
1. When making a request, include an Authorization header with the value Bearer
<Your Dummy Token>. Replace <Your Dummy Token> with the token you
received from the /dummy-token endpoint.
1. When making a request, include an Authorization header with the value Bearer
<Your Dummy Token>. Replace <Your Dummy Token> with the token you
received from the /dummy-token endpoint.
2. Now you can make requests to the protected endpoints of the application.
Remember, the dummy JWT is meant for testing purposes only and should not be
used in production environments. The /dummy-token endpoint is not available
Remember, the dummy JWT is meant for testing purposes only and should not be
used in production environments. The /dummy-token endpoint is not available
in non-local environments.
# Custom Domain Setup for AWS API Gateway
Before you deploy your Serverless application for the first time, you need to set up a custom domain for AWS API Gateway. This is done using the sls create_domain command, which creates a custom domain in API Gateway that your services can use.
Before you deploy your Serverless application for the first time, you need to set up a custom domain for AWS API
Gateway. This is done using the sls create_domain command, which creates a custom domain in API Gateway that your
services can use.
To set up a custom domain, use the following command:
@ -115,51 +125,98 @@ To set up a custom domain, use the following command:
sls create_domain --stage dev --aws-profile DevAdmin --verbose
```
Replace dev with the name of the stage you're deploying to. This command only needs to be run once per custom domain,
and not every time you deploy your application. After running this command,
you can associate your AWS Lambda functions with this domain using the customDomain
Replace dev with the name of the stage you're deploying to. This command only needs to be run once per custom domain,
and not every time you deploy your application. After running this command,
you can associate your AWS Lambda functions with this domain using the customDomain
configuration in your serverless.yml file.
This command requires the Serverless Domain Manager plugin,
This command requires the Serverless Domain Manager plugin,
so make sure you have it installed and properly configured in your serverless.yml file.
Please note that the process of creating and associating a custom domain can take up to 40 minutes.
Please note that the process of creating and associating a custom domain can take up to 40 minutes.
Once the custom domain is created, it's immediately available for use in your Serverless applications.
Remember to replace DevAdmin with the profile that has appropriate permissions in your AWS account.
The --verbose flag is optional and is used to print detailed logs to the console.
Remember to replace DevAdmin with the profile that has appropriate permissions in your AWS account.
The `--verbose` flag is optional and is used to print detailed logs to the console.
# Creating a CNAME Record in Google Domains
After deploying the AWS Lambda function for the first time, you need to set up a
CNAME record in Google Domains to route traffic from your custom domain to
the CloudFront distribution created by API Gateway. This will re-route traffic from
your custom domain to the CloudFront distribution created by API Gateway, and
therefore to your lambda.
You can find the CloudFront
domain by going to the API Gateway console and clicking on Custom Domain Names.
Here are the steps to create a CNAME record:
1. Log in to Google Domains.
2. Select the name of your domain.
3. Open the menu, if it's not already open.
4. Click "DNS."
5. Scroll down to the "Custom resource records" section.
6. In the "Name" field, enter your subdomain (e.g., api if your API is available at api.example.com).
7. In the "Type" dropdown menu, select "CNAME."
8. In the "TTL" field, enter 1H to set it to 1 hour (or another suitable value).
9. In the "Data" field, enter the CloudFront domain that was created by API Gateway (you can find this in the API
Gateway console, under Custom Domain Names).
10. Click "Add."
### Thoughts for authenticating the frontend with the backend
To provide secure communication between your frontend Next.js application and your backend FastAPI service, you have several options. Here are a few popular approaches:
- JWT (JSON Web Tokens): Since you're already using JWT for authentication in the frontend, you can also use this to authenticate requests to your FastAPI backend. This involves passing the JWT token in the Authorization header of the request from your frontend to the backend. Then, you can use a JWT decoder on the backend to validate the token. This can be done using libraries such as PyJWT in your FastAPI application.
To provide secure communication between your frontend Next.js application and your backend FastAPI service, you have
several options. Here are a few popular approaches:
- API Keys: This is another common approach where you issue unique keys for each user/service that needs to access the backend API. Each API call then includes this key in the request header. FastAPI can easily validate these keys. While this approach is simpler than JWT, it provides less flexibility and security, as it doesn't allow for claims or scopes.
- JWT (JSON Web Tokens): Since you're already using JWT for authentication in the frontend, you can also use this to
authenticate requests to your FastAPI backend. This involves passing the JWT token in the Authorization header of the
request from your frontend to the backend. Then, you can use a JWT decoder on the backend to validate the token. This
can be done using libraries such as PyJWT in your FastAPI application.
- OAuth2.0: OAuth2 is a protocol that allows applications to request authorization to access resources on behalf of a user. FastAPI has direct support for OAuth2 using the OAuth2PasswordBearer class, which can be used for issuing access tokens to clients. Note that this could be overkill if you're already using JWT and the calls to your backend are not on behalf of a user.
- API Keys: This is another common approach where you issue unique keys for each user/service that needs to access the
backend API. Each API call then includes this key in the request header. FastAPI can easily validate these keys. While
this approach is simpler than JWT, it provides less flexibility and security, as it doesn't allow for claims or
scopes.
- Mutual TLS (mTLS): Mutual TLS is a method of two-way communication encryption where both client and server authenticate each other. This can be more complex to setup but can provide an additional layer of security in some scenarios.
- OAuth2.0: OAuth2 is a protocol that allows applications to request authorization to access resources on behalf of a
user. FastAPI has direct support for OAuth2 using the OAuth2PasswordBearer class, which can be used for issuing access
tokens to clients. Note that this could be overkill if you're already using JWT and the calls to your backend are not
on behalf of a user.
No matter which method we choose, you should always serve your applications over HTTPS to ensure that all data, including tokens or keys, is encrypted during transmission.
Also, ensure that you handle the JWT tokens carefully, especially if they are stored in the client's browser, as they could be vulnerable to Cross-Site Scripting (XSS) or Cross-Site Request Forgery (CSRF) attacks. Consider httpOnly cookies for storing tokens if your use case allows it.
- Mutual TLS (mTLS): Mutual TLS is a method of two-way communication encryption where both client and server
authenticate each other. This can be more complex to setup but can provide an additional layer of security in some
scenarios.
No matter which method we choose, you should always serve your applications over HTTPS to ensure that all data,
including tokens or keys, is encrypted during transmission.
Also, ensure that you handle the JWT tokens carefully, especially if they are stored in the client's browser, as they
could be vulnerable to Cross-Site Scripting (XSS) or Cross-Site Request Forgery (CSRF) attacks. Consider httpOnly
cookies for storing tokens if your use case allows it.
### I think that we could use both JWT + API Key.
# Notes:
Using both JWT and API keys can provide an additional layer of security and
Using both JWT and API keys can provide an additional layer of security and
could be a good approach for our requirements.
1. JSON Web Tokens (JWT) are useful for carrying user context between services. With JWT, you can embed user-specific data (like user ID, roles, permissions, etc.) in a secure, tamper-proof token. This can be validated by your FastAPI backend to authenticate and authorize the user.
2.
3. API Keys can serve as an identifier for the client application (in this case, your Next.js frontend). It can provide a straightforward way to track and control how the client application is calling the backend API.
1. JSON Web Tokens (JWT) are useful for carrying user context between services. With JWT, you can embed user-specific
data (like user ID, roles, permissions, etc.) in a secure, tamper-proof token. This can be validated by your FastAPI
backend to authenticate and authorize the user.
2.
3. API Keys can serve as an identifier for the client application (in this case, your Next.js frontend). It can provide
a straightforward way to track and control how the client application is calling the backend API.
Here's a rough workflow of how these can be used together:
A user logs in to the Next.js frontend using NextAuth and receives a JWT.
This JWT is stored securely in the client's browser.
For each request from the frontend to the backend, the JWT is included in the Authorization header.
In addition to the JWT, an API key unique to the frontend application is included in each request (possibly in a custom header like X-API-Key).
The backend service validates both the JWT (for user authentication and authorization) and the API key (for client application validation).
In addition to the JWT, an API key unique to the frontend application is included in each request (possibly in a custom
header like X-API-Key).
The backend service validates both the JWT (for user authentication and authorization) and the API key (for client
application validation).
This approach provides a double check for each request:
The JWT verifies that the request comes from a legitimate, authenticated user.

View file

@ -29,7 +29,6 @@ custom:
useDocker: true
dockerSsh: true
fileName: requirements/base.txt
# dockerRunCmdExtraArgs: ['--platform', 'linux/amd64']
customDomain:
domainName: api.${self:provider.environment.DOMAIN_NAME}
createRoute53Record: true