You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在AWS S3托管的HTML网站中如何隐藏API访问密钥?

解决S3静态网站API Gateway访问密钥泄露的安全方案

嘿,这个问题问到点子上了——前端暴露密钥一直是静态网站的老大难,尤其是S3托管的纯前端项目,毕竟所有前端资源都是公开可下载的,硬编码密钥等于直接把钥匙送出去。我给你拆解几个靠谱的方案,从最安全到最实用的都有:

绝对不能做的事(划重点!)

  • 不要把访问密钥硬编码在JavaScript文件、HTML代码里,哪怕是压缩混淆过也不行——任何人打开浏览器开发者工具就能拿到。
  • 不要把密钥存在S3的配置文件、静态资源里,哪怕是私有存储桶也不行,因为前端请求的资源都是公开可访问的。

方案1:用IAM角色+API Gateway资源策略(最推荐,完全不用密钥)

既然你的网站托管在AWS生态里,完全可以绕开“前端存密钥”这个坑,用AWS的身份验证体系来控制访问:

  1. 给API Gateway配置资源策略
    • 编写策略只允许来自你的S3网站域名(比如https://your-s3-domain.com)的请求调用API;如果用了CloudFront加速,也可以限制为CloudFront的分发域名或IP范围。
    • 示例策略核心逻辑:
      {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:123456789012:abc123/*/*/*",
            "Condition": {
              "StringEquals": {
                "aws:Referer": "https://your-s3-domain.com"
              }
            }
          }
        ]
      }
      
  2. 额外加固:配合AWS WAF添加速率限制、验证码(比如reCAPTCHA)或者IP白名单,进一步防止恶意调用。

这种方案完全不需要在前端放任何密钥,所有访问控制都在AWS后端完成,是最安全的做法。

方案2:用Cognito身份池(适合有用户体系的场景)

如果你的网站需要用户登录,或者想区分匿名/已认证用户的访问权限,可以用Cognito身份池生成临时凭证:

  • 创建Cognito身份池,开启“未认证身份”(如果允许匿名用户提交表单),并给身份池附加IAM策略,只允许调用你的API Gateway。
  • 前端用AWS Amplify或AWS SDK获取临时凭证(这些凭证有过期时间,一般1小时),然后带着凭证调用API Gateway。
  • 好处是临时凭证就算泄露,有效期短,且权限被严格限定,风险极低;还能追踪用户的请求行为。

方案3:API密钥+CloudFront Lambda@Edge(次选,适合必须用密钥的场景)

如果你因为某些原因一定要用API Gateway的API密钥,绝对不能直接给前端,而是通过CloudFront的边缘函数来隐藏密钥:

  1. 给API Gateway创建API密钥和使用计划:把密钥关联到你的API资源上,只有带正确x-api-key头的请求才能通过。
  2. 配置CloudFront分发:把分发的源指向你的API Gateway域名。
  3. 创建Lambda@Edge函数:在“查看请求”触发器里,给请求添加x-api-key头,值就是你的API密钥。函数逻辑大概是:
    exports.handler = (event, context, callback) => {
      const request = event.Records[0].cf.request;
      request.headers['x-api-key'] = [{ key: 'x-api-key', value: 'YOUR_API_KEY' }];
      callback(null, request);
    };
    
  4. 限制CloudFront访问:给CloudFront配置缓存策略,同时设置Origin Access Control(OAC),只允许你的S3网站域名请求CloudFront。

这样前端只需要请求CloudFront的域名,完全不知道密钥的存在,密钥只在Lambda@Edge函数里(而Lambda@Edge的代码是托管在AWS内部的,不会暴露给用户)。


额外安全建议

  • 不管用哪种方案,都要给API Gateway设置速率限制,防止恶意刷接口。
  • 开启API Gateway的访问日志,定期检查异常请求(比如来自陌生域名/IP的大量请求)。
  • 对API的请求体做校验,防止注入攻击。

内容的提问来源于stack exchange,提问作者Ergun

火山引擎 最新活动