LoginSignup
27
45

More than 5 years have passed since last update.

【rails】S3でheroku上で画像保存しようとしたらエラー大量発生【Access denied】

Last updated at Posted at 2018-12-31

Heroku上の投稿サイトで画像が表示されない

画像を投稿するとこんな感じになります。
文字列の羅列みたいになってますね・・・
スクリーンショット (156).png

解決方法

ざっくりと解決方法と書きましたが、解決に至るまでにたくさんのエラーが出たため、以下にすべて記載してみました。
まずは、本番環境の保存先であるS3バケットの作成からでした。

AWS S3でバケットを作成する

参考にしたサイトRailsアプリをHerokuにデプロイ後、画像アップロードをAWS S3+carriewaveで設定する方法

こちらのサイトがとてもわかりやすかったので、AWSでのS3のバケット作成などは、記載のとおりに進めました。

↓carrierwave.rbファイルはこちら


#carrierwave.rb

require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'

if Rails.env.production?
CarrierWave.configure do |config|
  config.cache_dir = "#{Rails.root}/tmp/uploads"
  config.fog_provider = 'fog/aws'
  config.fog_credentials = {

    provider: 'AWS',
    region:  ENV['S3_REGION'],
    aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
    aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],

  }
  config.fog_directory  = ENV['S3_BUCKET']
end
end

heroku内での環境変数設定も忘れずに。以下のように設定することで、githubなどの一般公開するページに乗せた際にAWSのキーが漏洩するのを防げます。漏洩した場合、ものすごい金額の請求が来た例もあります。ネットで検索するといくつかでてきます。
なので、キーの設定は環境変数で設定しましょう。

heroku config:set AWS_ACCESS_KEY_ID=自分のアクセスキーID
heroku config:set AWS_SECRET_ACCESS_KEY=自分のシークレットアクセスキー
heroku config:set S3_BUCKET=自分のバケット
heroku config:set S3_REGION=ap-northeast-1

設定完了です。

herokuにデプロイ後、「We're sorry, but something went wrong.」が発生した。

よし、herokuにデプロイし、本番環境でアプリを開き、投稿しようとすると、We're sorry, but something went wrong.が発生しました。
おなじみの画面。
スクリーンショット (197).png

エラー1 「リージョンが違うよ」

こちら[Ruby on Rails Tutorial]Herokuにデプロイ後Application error[H10 (App crashed)]が発生した時の対処法のサイトを参考に、原因を探ってみます。

heroku logsを実行してみる。

(略)
The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'ap-northeast-1'
(略)

前後省略してみましたが、おそらくこれが原因っぽいですね。。。

ユーザーを作り直してみた

【Rails】S3へ『CarrierWave+fog』を使って画像アップロードする方法
とりあえず何してもだめだったので、こちらのサイトを参考にバケット、ユーザー、グループの作成を最初からやり直しました。

気づき1 IAMユーザーでAWSにログインしていなかった

ルートーユーザーでサインインをしており、通常のコンソール上でS3バケットを作成していました。
仕組みについてはよく理解していないのですが、上記のサイトに従えば問題ないかと思います。

気づき2(そもそもの管理リージョンが違うからおかしい?)

southeast(シンガポール)でやっているから?

バケットはnorth(東京)でやったほうがいいよ!とほかのブログでもおすすめされているのですが、cloud9はnorth(東京)をカバーしていないはず。。。なので、ルートユーザーでは、そのままsoutheastでやり、IAMユーザーのマネジメントコンソールは右上のリージョンがシンガポールになっていたのでそれを東京に修正しました。
すると、同じエラーはでなくなりました。しかしさらなるエラーが…

エラー2 「AWSキーが合わない」

やりなおしてもう一度herokuをデプロイし、画像を投稿しようとすると次はこのエラー。

#ターミナルでheroku logsを実行した結果

The request signature we calculated does not match the signature you provided. Check your key and signing method.

ひいい次はキーが合わないと言われている・・・
どうすりゃいいんだ・・・
とその時、気づきました・・・

エラー2の解決法 単純にキーの入力ミス

ユーザーを作成したときに、AWSIDとシークレットキーをエクセルファイルのcsvファイルでダウンロードできるのですが、私のパソコンがなぜかソフトのライセンス認証がいろいろあってとれていなくて、ファイルダウンロードしましたが、目で確認してherokuの環境変数に入力したのですね。
それでエクセルファイルに入力したときに、小文字のlと大文字のIを区別をミスってて、キーの入力間違いがあった可能性が考えられます・・なんとも恥ずかしいミス。

エラー3 「S3へのアクセスが拒否されました」

heroku logsをしてみると、キーが間違っているとは表示されなくなりましたが、その代わり別のエラーが・・・今回のタイトルにあるAccessdeniedです。

Excon::Error::Forbidden (Expected(200) <=> Actual(403 Forbidden)
2018-12-15T12:25:43.790917+00:00 app[web.1]: excon.error.response
2018-12-15T12:25:43.790923+00:00 app[web.1]: :body          => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>D88521220601A84D</RequestId><HostId>01z1R4aggIKUOnx2mjTE+3mqZYYhIY38Ehm2dkwl1SL5Zdf4tOQhUQLs4pWIDZc5+IUYoI17Ji0=</HostId></Error>"

エラー3の解決先

エラーAccess Denied 〜Rails + Carrierwave + HerokuでAWS S3に画像を保存〜
teratailに質問を投稿したところ、この記事を参考にしましたとのコメントをいただきました。
この記事によると、私とちょうど同じ時期に全く同じエラーで悩まれていたとのこと、この方はご自分でいろいろと検索をされて解決されたとのこと。すごい!AWSがちょうどこの時期に新しい機能を追加していたのですね。。。それはいくら探してもみつからないはずだ・・・

heroku logsで見てみるとAccess Deniedの文字が...
ここからはS3の新機能が働いてしまっているようです。
2018/11/15に発表されたパブリックアクセス設定機能のおかげでデフォルトでは管理者しかアクセスできず、IAMユーザーのアクセスがブロックされているという結論に至りました。

そんなこんなで私も同じようにやってみます。

まずはマネジメントコンソールからS3のページにいき、作成済のバケットを選択します。私はIAMユーザーでログインしてできましたが、ルートユーザーからS3編集しても問題ないと思います。

パブリックアクセス設定をデフォルトの状態から編集

以下のようにチェックボックスを設定してください。
スクリーンショット (308).png

結果、このように表示されます。
スクリーンショット (309).png

バケットポリシーを編集する

スクリーンショット (310).png

次に上の画像のとおりにバケットポリシーをクリックし、バケットポリシーエディタを開きます。以下のように入力します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "statement1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<あなたのAWS12桁のID>:user/<あなたのIAMユーザー名>"
            },
            "Action": "*",
            "Resource": "arn:aws:s3:::<あなたのバケット名>/*"
        }
    ]
}

<>は入力する必要はなし。自分のIDと数字をそのまま入力します。

結果、、本番環境でできたああああ!!

スクリーンショット (311).png

まとめ S3難しい・エラーがでないためのポイントまとめ

確認することは以下の点かと思われます。

1 環境変数が誤っていないか?コマンドにheroku configと打ち入力ミスがないか確認する。
2 バケットのリージョンとIAMユーザーのリージョンが一致しているか
3 IAMユーザーにS3FullAccessのポリシーがアタッチされているか
4 S3のバケットポリシーを編集しているか

間違っていたらご指導・ご指摘よろしくお願いします。

その他参考サイト

Herokuで本番環境のファイルの保存先をS3に設定する手順

27
45
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
45