対象者
- いろんな記事を見て回って試しているけど、S3からACCESS DENIED がずっと返って来る。
- 諦めたい
そんな人の助けになれば幸いです...!><
使ったもの
gem 'rails', '4.2.3'
# CarrierWave
gem 'carrierwave'
gem 'fog-aws'
carrierwave (1.3.1)
...
fog-aws (3.4.0)
でした。
概要
ACCESS DENIED を解決するために行ったAWS S3設定画像を貼っているだけです←本当にこれだけ
ACCESS DENIED を解決するための方法として、AWS S3の設定をいじるのはやめました。
(推奨)マークがついているものは全てチェックを維持したままでも、CarrierWave側のconfigに1行追加すれば ACCESS DENIED を回避できました。
AWSの設定、S3の作成、carrierewaveの設定については、いろんな記事があって私が解説する必要もないので、私が使用した記事を掲載するにとどめます。
やり方
AWSの準備、S3バケットの作成
エラーAccess Denied 〜Rails + Carrierwave + HerokuでAWS S3に画像を保存〜
Railsコードの記述、CarrierWaveの設定
【Rails5】Carrierwave + Fog で AWS S3 に画像をアップロードする
参考(エラーの対処と、CarrierWaveの設定項目の解説)
実際に行った設定
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'
CarrierWave.configure do |config|
if Rails.env.production? || Rails.env.development? # 開発中もs3使う
config.storage :fog
config.fog_provider = 'fog/aws'
config.fog_directory = 'バケット名'
config.asset_host = 'https://s3.amazonaws.com/バケット名'
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: 'AWS_ACCESS_KEY_ID',
aws_secret_access_key: 'AWS_SECRET_ACCESS_KEY',
region: 'us-east-2',
# path_style: true
}
else
config.storage :file
config.enable_processing = false if Rails.env.test?
end
end
class HogeUploader < CarrierWave::Uploader::Base
storage :fog
def store_dir
"carrierwave-test-siruku6/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
発生したエラー
Completed 500 Internal Server Error in 6490ms (ActiveRecord: 5.4ms)
Excon::Error::Forbidden (Expected(200) <=> Actual(403 Forbidden)
excon.error.response
:body => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>xxxxxxxx</RequestId><HostId>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</HostId></Error>"
:cookies => [
]
:headers => {
"Connection" => "close"
"Content-Type" => "application/xml"
"Date" => "Sat, 16 Mar 2019 17:05:27 GMT"
"Server" => "AmazonS3"
"x-amz-id-2" => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"x-amz-request-id" => "xxxxxxxxxxxxxxxx"
}
:host => "バケット名.s3.us-east-2.amazonaws.com"
:local_address => "xxx.xxx.xxx.xxx"
:local_port => 44250
:path => "/xxxxxxxxxxxxxxx/uploads/xxxxxxxx/xxxxxxxxx/1/fx%E6%90%8D%E7%9B%8A.pdf"
:port => 443
:reason_phrase => "Forbidden"
:remote_ip => "xxx.xxx.xxx.xxx"
:status => 403
:status_line => "HTTP/1.1 403 Forbidden\r\n"
):
app/controllers/hoge_controller.rb:14:in `upload'
むぐぐ
やむを得ず行った変更(AWS S3)
1つチェックを外して設定を保存した
セキュリティが落ちるので、チェックを外すのはやめました。
代替策(設定変更)
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'
CarrierWave.configure do |config|
if Rails.env.production? || Rails.env.development? # 開発中もs3使う
config.storage :fog
config.fog_provider = 'fog/aws'
config.fog_directory = 'バケット名'
config.asset_host = 'https://s3.amazonaws.com/バケット名'
# NOTE: AWS側の設定を変えなくても、この1行の設定でアップロードできた
config.fog_public = false # ←コレ
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: 'AWS_ACCESS_KEY_ID',
aws_secret_access_key: 'AWS_SECRET_ACCESS_KEY',
region: 'us-east-2',
# path_style: true
}
else
config.storage :file
config.enable_processing = false if Rails.env.test?
end
end
これでアップロードできた!
参考にしたサイト
【Ruby on Rails】carrierwave-awsを使ってAWSのS3に画像をアップロードするときにAws::S3::Errors::AccessDeniedのエラー対処法
この人はチェック3つ外してるけど、一番上の1つだけでも動いたよ。
その他
stackoverflowにはこんなこと書かれてるけど、これは試してないです
Excon::Errors::Forbidden (Expected(200) <=> Actual(403 Forbidden)
考えたこと
- 「パブリックオブジェクトのアップロードをブロックする」という設定が有効
- config.fog_public = true または config.fog_public を設定していない
この2つの条件を両方満たすと、403エラーになるようだ。
fog_publicというのは、パブリックオブジェクトとしてアップロードするかどうかの設定だったみたい。