0

我正在尝试通过 CarrierWave 将图像上传到 S3,但不断收到 500 内部服务器错误 - Aws::S3::Errors::AccessDenied。我正在使用 ruby​​ gem CarrierWave 来配置 AWS 和 dotenv-rails 以在 .env 文件中调用和隐藏我的凭据。看来我的代码工作正常,但我被拒绝访问我的存储桶。这是我第一次尝试将 AWS 集成到项目中,因此我的配置可能会因此而关闭。任何帮助将不胜感激。

我已经尝试重置我的访问密钥并确保我的区域设置正确。我什至更改了区域并收到一个错误提示我将其更改回正确的区域:“us-west-1”。我通过确保我可以通过 rails 控制台获取我的凭据来确保 dotenv-rails 正常工作。我还使用“byebug”在我的投资组合控制器中的更新操作中设置了一个断点,以便自己手动输入更新代码。我可以看到我正在尝试更新我的投资组合项目的新图像,但它总是回滚。

投资组合控制器.rb:

class PortfoliosController < ApplicationController
    before_action :set_portfolio, only: [:show, :edit, :update, :destroy]

    layout "portfolio"

    access all: [:show, :index, :javascript], user: {except: [:destroy, :new, :create, :update, :edit, :sort]}, site_admin: :all

    def index
        @portfolio_items = Portfolio.by_position
    end

  def sort
    params[:order].each do |key, value|
      Portfolio.find(value[:id]).update(position: value[:position])
    end

    render :index
  end

    def javascript
        @javascript_portfolio_items = Portfolio.javascript
    end

    def new
        @portfolio_item = Portfolio.new
        3.times { @portfolio_item.technologies.build }
    end

    def show
    end

    def create
    @portfolio_item = Portfolio.new(portfolio_params)

    respond_to do |format|
      if @portfolio_item.save
        format.html { redirect_to portfolios_path, notice: 'Portfolio item was successfully created.' }
      else
        format.html { render :new }
      end
    end
    end

    def edit
    end

    def update
            respond_to do |format|
                if @portfolio_item.update(portfolio_params)
                    format.html { redirect_to portfolios_path, notice: 'Portfolio item was successfully updated.' }
                else
                    format.html { render :edit }
                end
            end
    end

    def destroy
        @portfolio_item.destroy

    respond_to do |format|
      format.html { redirect_to portfolios_url, notice: 'Portfolio item was successfully deleted.' }
    end
    end

    private
    # Use callbacks to share common setup or constraints between actions.
    def set_portfolio
        @portfolio_item = Portfolio.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def portfolio_params
        params.require(:portfolio).permit(:title, 
                                                                            :subtitle, 
                                                                            :main_image,
                                                                            :thumb_image,
                                                                            :body, 
                                                                            technologies_attributes: [:id, :name, :_destroy]
                                                                            )
    end

end

载波.rb:

CarrierWave.configure do |config|
  config.storage    = :aws
  config.aws_bucket = ENV.fetch('S3_BUCKET_NAME')
  config.aws_acl    = 'public-read'
  config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7
  config.aws_attributes = {
    expires: 1.week.from_now.httpdate,
    cache_control: 'max-age=604800'
  }

   config.aws_credentials = {
    access_key_id:     ENV.fetch('AWS_ACCESS_KEY_ID'),
    secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
    region:            ENV.fetch('AWS_REGION') # Required
  }
end 

投资组合上传器.rb:

class PortfolioUploader < CarrierWave::Uploader::Base

  storage :aws

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  def extension_whitelist
    %w(jpg jpeg gif png)
  end

end

导轨服务器:

Started PATCH "/portfolios/10" for 127.0.0.1 at 2019-02-13 14:42:36 -0600
Processing by PortfoliosController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"rYMLuRSQkoq6Nx+4MdXulBMCaBTRZm0xAm1qVLWf9QYnZewSPFXylE/HSK/1kXliZqX+pt4J+6YPjCslcgc9AA==", "portfolio"=>{"title"=>"Updated", "subtitle"=>"Javascript", "main_image"=>#<ActionDispatch::Http::UploadedFile:0x00007fe00d14f6f0 @tempfile=#<Tempfile:/var/folders/8c/dyl1g215043d3hk1gzq9bz4h0000gn/T/RackMultipart20190213-59215-1dc56wv.png>, @original_filename="b7jlq5pf52m11.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"portfolio[main_image]\"; filename=\"b7jlq5pf52m11.png\"\r\nContent-Type: image/png\r\n">, "thumb_image"=>#<ActionDispatch::Http::UploadedFile:0x00007fe00d14f678 @tempfile=#<Tempfile:/var/folders/8c/dyl1g215043d3hk1gzq9bz4h0000gn/T/RackMultipart20190213-59215-1ay0r07.png>, @original_filename="b7jlq5pf52m11.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"portfolio[thumb_image]\"; filename=\"b7jlq5pf52m11.png\"\r\nContent-Type: image/png\r\n">, "body"=>"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris eget volutpat lectus. Donec neque urna, mattis ut fermentum non, iaculis sed est. Vestibulum odio tortor, scelerisque id maximus id, dignissim at turpis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Praesent in magna vitae enim condimentum sollicitudin. Proin lobortis euismod velit. Aenean ac nibh a augue tempus dapibus eu sollicitudin leo. Fusce lorem arcu, tempor a ligula vitae, tincidunt finibus augue. Maecenas tempor odio sit amet molestie congue. Vestibulum porttitor neque dui, sit amet pharetra elit feugiat sit amet.", "technologies_attributes"=>{"0"=>{"name"=>"Technology 0", "id"=>"1"}, "1"=>{"name"=>"Technology 1", "id"=>"2"}, "2"=>{"name"=>"Technology 2", "id"=>"3"}, "3"=>{"name"=>"Technology 123", "id"=>"4"}, "4"=>{"name"=>"Technology 1", "id"=>"5"}, "5"=>{"name"=>"Technology 2", "id"=>"6"}, "6"=>{"name"=>"Technology 0", "id"=>"7"}, "7"=>{"name"=>"Technology 1", "id"=>"8"}, "8"=>{"name"=>"Technology 2", "id"=>"9"}, "9"=>{"name"=>"Technology 123", "id"=>"10"}, "10"=>{"name"=>"Technology 1", "id"=>"11"}, "11"=>{"name"=>"Technology 2", "id"=>"12"}}}, "commit"=>"Save Portfolio Item", "id"=>"10"}
  Portfolio Load (1.5ms)  SELECT  "portfolios".* FROM "portfolios" WHERE "portfolios"."id" = $1 LIMIT $2  [["id", 10], ["LIMIT", 1]]
  ↳ app/controllers/portfolios_controller.rb:68
  User Load (1.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/concerns/current_user_concern.rb:5
   (0.2ms)  BEGIN
  ↳ app/controllers/portfolios_controller.rb:49
  Technology Load (1.1ms)  SELECT "technologies".* FROM "technologies" WHERE "technologies"."portfolio_id" = $1 AND "technologies"."id" IN ($2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)  [["portfolio_id", 10], ["id", 1], ["id", 2], ["id", 3], ["id", 4], ["id", 5], ["id", 6], ["id", 7], ["id", 8], ["id", 9], ["id", 10], ["id", 11], ["id", 12]]
  ↳ app/controllers/portfolios_controller.rb:49
  Portfolio Update (0.7ms)  UPDATE "portfolios" SET "main_image" = $1, "thumb_image" = $2, "updated_at" = $3 WHERE "portfolios"."id" = $4  [["main_image", "b7jlq5pf52m11.png"], ["thumb_image", "b7jlq5pf52m11.png"], ["updated_at", "2019-02-13 20:42:36.732254"], ["id", 10]]
  ↳ app/controllers/portfolios_controller.rb:49
   (0.4ms)  ROLLBACK
  ↳ app/controllers/portfolios_controller.rb:49
Completed 500 Internal Server Error in 391ms (ActiveRecord: 18.3ms)



Aws::S3::Errors::AccessDenied (Access Denied):

app/controllers/portfolios_controller.rb:49:in `block in update'
app/controllers/portfolios_controller.rb:48:in `update'

我希望这能够工作并能够访问 AWS 资源,但也许我需要为我的存储桶设置一些配置?到目前为止,AWS 文档一直难以消化。我可以使用帮助,谢谢。

4

1 回答 1

1

已修复:必须进入 AWS 仪表板并更改我尝试访问的 S3 存储桶的公共访问设置。您可以通过访问 AWS 控制面板导航到它,选择 S3 资源,选择您尝试访问的存储桶,然后进入它的属性菜单。我只是将所有内容都设置为假。可以在此处对各个设置进行更多说明。

管理公共访问控制列表 (ACL)

阻止新的公共 ACL 和上传公共对象:

错误的

删除通过公共 ACL 授予的公共访问权限:

错误的

管理公共存储桶策略

阻止新的公共存储桶策略:

错误的

如果存储桶具有公共策略,则阻止公共和跨账户访问:

错误的

于 2019-03-03T01:47:32.750 回答