关于 static-frontend-hosting
面向工程师的静态前端托管参考技能,介绍使用 S3、CloudFront 和 Lambda@Edge 实现基于令牌的访问,无需登录界面,并说明区域限制和部署流程。
主要功能
- 01使用 S3 托管静态文件
- 02通过 CloudFront 分发内容
- 03使用 Lambda@Edge 验证令牌
- 04通过 Origin Access Control 保护 S3
- 05提供多区域部署指导
适用场景
- 01托管仅限邀请访问的演示应用
- 02提供受限访问的营销内容
- 03展示客户专属文档视图
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ loxosceles-dev/ dev-skills --skill static-frontend-hosting安装后在 Claude Code 中输入/static-frontend-hosting确认已加载。
详细介绍
使用边缘身份验证托管静态前端
这是一种参考模式。 从中了解做法,并根据自己的情况进行调整——不要照搬。
问题:需要低成本、全球分布式的前端托管,并支持身份验证,但不要求用户登录。
解决方案:使用 S3 托管静态网站,通过 CloudFront CDN 和 Lambda@Edge 实现透明身份验证。
模式
架构:
User Request
↓
CloudFront (CDN)
↓
Lambda@Edge (us-east-1) ← Validates token, sets cookies
↓
S3 Bucket (Static Files)
关键组件:
- S3 Bucket:托管静态前端构建产物(HTML、JS、CSS)
- CloudFront:用于快速交付内容的全球 CDN
- Lambda@Edge:拦截请求以处理身份验证
- Origin Access Control:保护 S3 Bucket(只有 CloudFront 可以访问)
为什么使用此模式?
优点:
- 低成本:无需全天候运行服务器,只需为存储和带宽付费
- 全球性能:CloudFront 在全球各地设有边缘站点
- 可扩展性:自动应对流量激增
- 透明身份验证:用户通过链接完成身份验证,无需登录界面
- 静态安全性:没有服务器端漏洞,只有静态文件
使用场景:
- 提供个性化访问的作品集网站
- 仅限受邀用户访问的演示应用
- 提供受限内容的营销网站
- 为不同客户提供专属视图的文档
实现
S3 Bucket:
const websiteBucket = new s3.Bucket(this, 'WebsiteBucket', {
bucketName: `${PROJECT_ID}-web-${environment}`,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, // Not public!
removalPolicy: cdk.RemovalPolicy.DESTROY
});
CloudFront Distribution:
const distribution = new cloudfront.Distribution(this, 'Distribution', {
defaultBehavior: {
origin: new origins.S3Origin(websiteBucket),
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
edgeLambdas: [{
functionVersion: authFunction.currentVersion,
eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST
}]
}
});
Lambda@Edge 函数:
export async function handler(event) {
const request = event.Records[0].cf.request;
const queryParams = new URLSearchParams(request.querystring);
const token = queryParams.get('token');
if (token) {
// Validate token (check signature, expiration, etc.)
const isValid = await validateToken(token);
if (isValid) {
// Set authentication cookie
return {
status: '302',
headers: {
'location': [{ value: '/' }],
'set-cookie': [{ value: `auth_token=${token}; Secure; HttpOnly` }]
}
};
}
}
// Check existing cookie
const cookies = request.headers.cookie?.[0]?.value || '';
if (cookies.includes('auth_token=')) {
return request; // Authenticated, proceed
}
// Not authenticated, show public view or error
return request;
}
关键权衡:Lambda@Edge 的区域要求
限制:Lambda@Edge 函数必须部署在 us-east-1 区域。
原因:CloudFront 是一项由 us-east-1 管理的全球服务。边缘函数会从该区域复制到全球各地。
影响:
- 用于托管网站的 CDK 堆栈必须部署到 us-east-1
- 如果主基础设施位于其他区域(例如 eu-central-1),则需要使用单独的堆栈
- 跨区域引用会变得复杂
解决方法:
// Main stack in eu-central-1
const mainStack = new MainStack(app, 'MainStack', {
env: { region: 'eu-central-1' }
});
// Web stack in us-east-1 (for Lambda@Edge)
const webStack = new WebStack(app, 'WebStack', {
env: { region: 'us-east-1' }
});
// Pass data via SSM Parameter Store, not direct references
部署流水线
构建流程:
- 构建静态前端(
npm run build) - 部署基础设施(S3、CloudFront、Lambda@Edge)
- 将静态文件上传到 S3
- 清除 CloudFront 缓存
示例:
# buildspec.yml
phases:
build:
commands:
- cd frontend && npm run build
- cd infrastructure && cdk deploy WebStack
- aws s3 sync frontend/out s3://${BUCKET_NAME}
- aws cloudfront create-invalidation --distribution-id ${DIST_ID} --paths "/*"
不适用场景
- 服务器端渲染:改用 ECS/Lambda 和 API Gateway
- 实时更新:改用 WebSocket API 和 Lambda
- 复杂身份验证流程:改用 Cognito Hosted UI 或自定义身份验证服务
- 频繁更新内容:考虑增量静态再生成或动态渲染
相关模式
渐进式改进
如果开发者纠正了此技能本应避免的行为,请提出对此技能的具体修订建议,以防止今后出现相同的问题。
评论
支持 Markdown