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

如何生成不暴露Bucket、IAM_KEY等信息的S3临时访问URL?

如何生成不暴露Bucket和IAM信息的S3临时URL?

我最近在用这段代码生成S3存储桶文件的临时URL用于网站展示:

export function PreURL(IAM_USER_KEY, IAM_USER_SECRET, BUCKET_NAME, Key1) { 
  let s3bucket = new AWS.S3({ 
    endpoint: 's3-us-west-1.amazonaws.com', 
    signatureVersion: 'v4', 
    region: 'us-west-1', 
    accessKeyId: IAM_USER_KEY, 
    secretAccessKey: IAM_USER_SECRET, 
    Bucket: BUCKET_NAME 
  }); 
  var params = {Bucket: BUCKET_NAME, Key: Key1, Expires: 60}; 
  var url = s3bucket.getSignedUrl('getObject', params); 
  console.log('Image The URL is', url); // expires in 60 seconds 
  return url.toString() 
} // End of PreURL

当前生成的URL格式类似这样:

https://BUCKET.s3-REGION.amazonaws.com/FILE?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=IAM_KEY%2F20200909%2FREGION%2Fs3%2Faws4_request&X-Amz-Date=TIME&X-Amz-Expires=60&X-Amz-Signature=SIGNATURE&X-Amz-SignedHeaders=HEADERS#t=0.1

这个URL直接暴露了Bucket名称、IAM_KEY等信息,虽然知道没有密钥就无法访问存储桶,但我还是希望生成不包含过多此类信息的临时URL,请问有没有其他实现方式?


针对这个需求,有几个可行的方案可以帮你减少URL里暴露的敏感信息:

方案1:使用CloudFront Signed URLs/Cookies + Origin Access Control (OAC)

这是最推荐的方案,既能隐藏S3的原始信息,还能获得CDN的加速优势:

  • 核心逻辑:将CloudFront作为前端访问的入口,把你的S3桶配置为CloudFront的源,并通过OAC限制只有CloudFront能直接访问S3。之后生成CloudFront的签名URL/Cookies,用户通过这个URL访问时,请求会先到CloudFront,再由CloudFront从S3拉取内容返回。
  • 优势:生成的URL使用CloudFront的自定义域名,不会包含S3 Bucket名称、IAM密钥等信息,签名参数也是针对CloudFront的,格式更简洁。同时CloudFront还能提供全球加速、缓存优化等额外功能。
  • 实现要点:需要先创建CloudFront分配,配置OAC并关联到S3桶,生成CloudFront密钥对,然后用AWS SDK(比如aws-sdk@aws-sdk/cloudfront-signer)生成签名URL。

方案2:使用S3访问点(Access Points)

这个方案可以隐藏原始的Bucket名称,虽然IAM_KEY还是会出现在签名参数中,但能减少一部分敏感信息的暴露:

  • 核心逻辑:为你的S3桶创建一个S3访问点,之后生成签名URL时,将参数中的Bucket替换为访问点的ARN或域名。生成的URL会使用访问点的域名,而不是原始的Bucket域名。
  • 优势:不需要额外的CDN服务,配置相对简单,能直接替换现有代码中的Bucket参数即可实现隐藏原始Bucket名的效果。

方案3:搭建后端代理服务

如果想要完全隐藏所有S3相关的信息,可以自己搭建一个简单的后端代理:

  • 核心逻辑:前端请求你的后端接口,后端在接口内部生成S3的签名URL,直接拉取S3的文件内容,然后将内容返回给前端,而不是把签名URL返回给前端。
  • 优势:前端看到的只有你的后端域名,完全看不到任何S3相关的信息,控制权完全在你手中。
  • 注意点:需要维护额外的后端服务,会增加一定的开发和运维成本,同时要考虑请求量带来的带宽和性能压力。

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

火山引擎 最新活动