从单个 S3 存储桶通过 AWS CloudFront 为 SPA 多租户提供服务
Serve SPA multi-tenants through AWS CloudFront from a single S3 bucket
考虑到以下因素:
- 包含静态前端 SPA 文件的单个 S3 存储桶。
- Frontend 通过 CloudFront 提供服务,其中每个租户都有自己的 CloudFront 分配(tenantA.domain.com,... tenantZ.domain.com)。
- 每个租户都有自己的配置(可以从解析域的配置服务中获取)。
- 每个 CloudFront 需要在 运行 时间在前端注入这样的配置。
我正在考虑一个 Lambda 函数,它查询“配置服务”(可能缓存响应),然后设置全局范围的变量(例如 window.config1
)供 SPA 使用。通过 CloudFront 可以实现这种情况吗?还有更多的common/standardized方法吗?
是的,你可以做到,我已经做到了! (一直想写一篇关于它的博客。
我在 multi-tenant SAAS 平台上工作,其中租户有自己的 Cognito 身份提供者配置。我所做的是我有一个文件 config.js
,看起来像这样有一堆 Cognito 设置:(我正在使用 ReactJS)
window.TENANT_CONFIG = {
REACT_APP_USERPOOL_REDIRECT_SIGNIN : "https://todo.somesite.com/",
REACT_APP_USERPOOL_REDIRECT_SIGNOUT : "https://todo.somesite.com/",
REACT_APP_WEB_CLIENT_ID : "todo",
REACT_APP_TENANT_NAME : "todo" ....
};
此图块作为 javascript 脚本包含在我的 index.html
顶部
<script type="text/javascript" src="%PUBLIC_URL%/config.js"></script>
Lambda
您需要 us-east-1
中的 Lambda 函数,它将在您的 Cloudfront 发行版中成为边缘的 Lambda。此函数必须只有 128 MB
并且没有环境变量。您可以参考 this 文档了解如何创建 Lambda 函数。但一般来说你需要构造window.TEN...
。您可以阅读 event.Records[0].cf.request.headers['host'][0].value
以确定您的呼叫是来自一个域还是另一个域,并构建适当的 config.js
文件。我的 Lambda 函数实际上是从 S3 存储桶中读取配置。你的会不一样。
CloudFront
如果可以生成正确的证书,实际上只需要一个 CloudFront
域。只需确保您已添加所有不同子域的 CName。然后您需要添加一个行为,其路径模式为:config.js
。配置 Viewer Request
的 Lambda Function Associations
并指定您的 Lambda Function ARN
。一切顺利!
考虑到以下因素:
- 包含静态前端 SPA 文件的单个 S3 存储桶。
- Frontend 通过 CloudFront 提供服务,其中每个租户都有自己的 CloudFront 分配(tenantA.domain.com,... tenantZ.domain.com)。
- 每个租户都有自己的配置(可以从解析域的配置服务中获取)。
- 每个 CloudFront 需要在 运行 时间在前端注入这样的配置。
我正在考虑一个 Lambda 函数,它查询“配置服务”(可能缓存响应),然后设置全局范围的变量(例如 window.config1
)供 SPA 使用。通过 CloudFront 可以实现这种情况吗?还有更多的common/standardized方法吗?
是的,你可以做到,我已经做到了! (一直想写一篇关于它的博客。
我在 multi-tenant SAAS 平台上工作,其中租户有自己的 Cognito 身份提供者配置。我所做的是我有一个文件 config.js
,看起来像这样有一堆 Cognito 设置:(我正在使用 ReactJS)
window.TENANT_CONFIG = {
REACT_APP_USERPOOL_REDIRECT_SIGNIN : "https://todo.somesite.com/",
REACT_APP_USERPOOL_REDIRECT_SIGNOUT : "https://todo.somesite.com/",
REACT_APP_WEB_CLIENT_ID : "todo",
REACT_APP_TENANT_NAME : "todo" ....
};
此图块作为 javascript 脚本包含在我的 index.html
<script type="text/javascript" src="%PUBLIC_URL%/config.js"></script>
Lambda
您需要 us-east-1
中的 Lambda 函数,它将在您的 Cloudfront 发行版中成为边缘的 Lambda。此函数必须只有 128 MB
并且没有环境变量。您可以参考 this 文档了解如何创建 Lambda 函数。但一般来说你需要构造window.TEN...
。您可以阅读 event.Records[0].cf.request.headers['host'][0].value
以确定您的呼叫是来自一个域还是另一个域,并构建适当的 config.js
文件。我的 Lambda 函数实际上是从 S3 存储桶中读取配置。你的会不一样。
CloudFront
如果可以生成正确的证书,实际上只需要一个 CloudFront
域。只需确保您已添加所有不同子域的 CName。然后您需要添加一个行为,其路径模式为:config.js
。配置 Viewer Request
的 Lambda Function Associations
并指定您的 Lambda Function ARN
。一切顺利!