mcpField
S
static-frontend-hosting

static-frontend-hosting

github.com/loxosceles-dev云与 DevOps167 次安装
代码仓库

关于 static-frontend-hosting

面向工程师的静态前端托管参考技能,介绍使用 S3、CloudFront 和 Lambda@Edge 实现基于令牌的访问,无需登录界面,并说明区域限制和部署流程。

主要功能

  1. 01使用 S3 托管静态文件
  2. 02通过 CloudFront 分发内容
  3. 03使用 Lambda@Edge 验证令牌
  4. 04通过 Origin Access Control 保护 S3
  5. 05提供多区域部署指导

适用场景

  1. 01托管仅限邀请访问的演示应用
  2. 02提供受限访问的营销内容
  3. 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

部署流水线

构建流程:

  1. 构建静态前端(npm run build)
  2. 部署基础设施(S3、CloudFront、Lambda@Edge)
  3. 将静态文件上传到 S3
  4. 清除 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