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

Ruby AWS SDK遍历S3存储桶对象生成可读URL问题求助

Fixing S3 Object URL Generation in AWS SDK for Ruby

Hey there! Let's get your S3 object URLs working properly. The issue here is that the url_for method you found in older docs doesn't work the same way in the current AWS SDK for Ruby (v3)—and there's a clearer way to get both public and private object URLs.

First, Let's Diagnose the Problem

In your code, when you loop over bucket.objects.each do |name|, that name variable is actually an Aws::S3::Object instance, not just the object's key. The old url_for(:read) syntax was from earlier SDK versions (like v1), which has been replaced with more explicit methods in v3.

Solution: Use the Right Methods for Your Object's Permissions

Depending on whether your S3 objects are public or private, use one of these approaches:

1. For Publicly Accessible Objects

If your objects are configured with public read permissions (or your bucket policy allows public access), use the public_url method directly on the object.

2. For Private Objects (Generate Presigned URLs)

For private objects, you'll need a pre-signed URL—this lets anyone access the object for a set period of time without making it public. Use the presigned_url(:get) method, which lets you set an expiration time (default is 1 hour).

Corrected Code

Here's how to update your method to generate both types of URLs (pick the one that fits your use case):

def aws_s3_url
  s3_client = Aws::S3::Resource.new(region: ENV['AWS_REGION'])
  bucket = s3_client.bucket(ENV['S3_BUCKET'])
  
  bucket.objects.each do |obj|
    puts "Object Key: #{obj.key}"
    
    # Option 1: Public URL (for objects with public read access)
    begin
      public_url = obj.public_url
      puts "Public Read URL: #{public_url}"
    rescue Aws::S3::Errors::AccessDenied
      puts "This object isn't publicly accessible—use a presigned URL instead."
    end
    
    # Option 2: Presigned URL (for private objects, valid for 1 hour by default)
    # Adjust expires_in to set how long the URL is valid (in seconds)
    presigned_url = obj.presigned_url(:get, expires_in: 3600)
    puts "Presigned Read URL: #{presigned_url}"
  end
end

Key Notes to Keep in Mind

  • Permissions Check: For public_url to work, your object must have the public-read ACL, or your bucket policy must grant public read access to the object.
  • IAM Permissions: To generate a presigned URL, the IAM user/role associated with your s3_client needs the s3:GetObject permission for the target objects.
  • Expiration Control: When using presigned_url, you can adjust the expires_in parameter to make the URL valid for minutes, hours, or even days (up to 7 days max, per AWS limits).

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

火山引擎 最新活动