adding custom domain back into serverless script

This commit is contained in:
Khalim Conn-Kowlessar 2023-08-24 13:17:19 +01:00
parent 22d6673aa3
commit 0371a810e7
2 changed files with 95 additions and 51 deletions

View file

@ -198,60 +198,104 @@ mapped to the appropriate API stage.
Remember to replace api and the CloudFront domain with your actual subdomain
and CloudFront domain.
### Thoughts for authenticating the frontend with the backend
Certainly! Here's a detailed documentation for your README:
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.
Deployment Troubleshooting for `fastapi-lambda`
-----------------------------------------------
- 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.
### Context:
- 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.
When deploying the `fastapi-lambda` using Serverless Framework, you may encounter issues related to domain management,
especially if you're using a custom domain for your API. This documentation provides troubleshooting steps and details
on how to resolve potential conflicts.
- 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.
### Potential Issues & Solutions:
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.
#### 1\. Conflict with Existing CloudFront Distribution:
### I think that we could use both JWT + API Key.
**Error Message**:
# Notes:
csharpCopy code
Using both JWT and API keys can provide an additional layer of security and
could be a good approach for our requirements.
`One or more aliases specified for the distribution includes an incorrectly configured DNS record that points to another CloudFront distribution.`
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.
**Cause**: This can occur if there's an existing CNAME record in your DNS provider pointing to a CloudFront
distribution.
Here's a rough workflow of how these can be used together:
**Solution**:
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).
This approach provides a double check for each request:
* Check your DNS provider (e.g., Google Domains) and verify the CNAME record for `api.dev.hestia.homes`.
* Temporarily remove or update the conflicting CNAME record.
* Run the `sls create_domain` command again.
* Update the DNS settings in your DNS provider based on the new configuration provided by
the `serverless-domain-manager` plugin.
#### 2\. Conflict with Route53:
**Error Message**:
csharpCopy code
`Deleting RestApi failed. Please remove all base path mappings related to the RestApi in your domains.`
**Cause**: This can occur if there are residual AWS configurations, especially in Route53, from previous deployments.
**Solution**:
* Navigate to the AWS Route53 Console.
* Identify and delete any residual Hosted Zones or Record Sets related to `api.dev.hestia.homes`.
* Ensure that you have backed up any necessary configurations before deleting.
#### 3\. Other AWS Resources Conflicts:
You might encounter issues where AWS resources, such as S3 buckets or CloudFront distributions, are not properly deleted
or are conflicting with new deployments.
**Solution**:
* Navigate to the respective AWS service dashboard.
* Manually identify and rectify any conflicting resources. This might involve emptying S3 buckets or deleting CloudFront
distributions.
* Ensure backups and proper precautions before deleting any resources.
### Additional Notes:
* **Backup Configurations**: Always backup your configurations before making changes. This ensures that you can revert
to a previous state if needed.
* **DNS Propagation**: Remember that DNS changes can take some time to propagate globally. After making DNS changes, you
might not see immediate effects.
* **CloudFront Distributions**: If you can't find a CloudFront distribution in the AWS CloudFront console, it's possible
that it was automatically created by another AWS service like API Gateway. It might need to be managed or deleted from
that service's dashboard.
### After succesfully running creating the custom domain
After successfully creating the custom domain with the `serverless-domain-manager` plugin, you should add back the CNAME
record into Google Domains (or whatever platform is being used to manage domains now)
to ensure that the custom domain properly points to the CloudFront distribution managed by
AWS.
Here's what you should do:
1. **Log in to Google Domains**:
* Go to [Google Domains](https://domains.google.com/).
* Navigate to the management page for `hestia.homes`.
2. **Add/Update the CNAME Record**:
* Find the section for custom resource records.
* Add (or update if it already exists) a CNAME record for `api.dev`.
* Point it to the CloudFront distribution domain name (e.g., `d2d269kjy1nyhz.cloudfront.net.`). Ensure you include
the trailing dot at the end. This can be found in API gateway
3. **Check DNS Propagation**:
* Keep in mind that DNS changes might take some time to propagate. You can use online tools
like [DNS Checker](https://www.dnschecker.org/) to verify the propagation status worldwide.
* Test your API endpoint `api.dev.hestia.homes` to ensure it's resolving correctly and accessing your Lambda
function.
By following these steps, you should have your custom domain properly configured and pointing to your AWS Lambda
function via the CloudFront distribution.
The JWT verifies that the request comes from a legitimate, authenticated user.
The API key verifies that the request comes from a trusted client application.

View file

@ -32,14 +32,14 @@ provider:
- arn:aws:s3:::${env:PLAN_TRIGGER_BUCKET}/*
#plugins:
# - serverless-domain-manager
plugins:
- serverless-domain-manager
#custom:
# customDomain:
# domainName: api.${self:provider.environment.DOMAIN_NAME}
# createRoute53Record: true
# certificateArn: ${ssm:/ssl_certificate_arn}
custom:
customDomain:
domainName: api.${self:provider.environment.DOMAIN_NAME}
createRoute53Record: true
certificateArn: ${ssm:/ssl_certificate_arn}
functions:
app: