#Laravelアプリで画像をS3に保存するように変更したらハマった話
##環境
Heroku
AWS(S3で画像を保存)
PHP 7.3
Laravel 8.8.0
MySQL 5.6.47
HTML
CSS
Blade
##背景
元々、Laravel8で作ったアプリのデプロイは、全ての機能をHerokuでデプロイしていました。しかし、投稿画像が一定時間を超えると画像がリンク切れを起こします。これはHerokuの仕様です。
この問題を解決すべく、画像の保存場所をAWSのS3に変更しました。環境変数の設定などを行い(これは、「Heroku Laravel S3」などでググれば出てきます)、いざ画像を投稿しようとしたら以下のようなエラーが出ました。
####①これで画像を投稿しようとすると……
####②こうなる
長い……。ちなみに画像なしでの投稿は問題なく行えます。画像を投稿するときだけこうなります。
####③とりあえず日本語にしてみる
日本語にしても焼け石に水。地道に解読します。
注目すべきは4行目の403Forbiddenという記述。
##403Forbiddenとは
Forbiddenとは「禁止する」という意味の英語。
403Forbiddenは、「何らかの理由でサイトが閲覧できない、もしくは禁止されている状態ですよ」というエラーです。
つまり、パーミッション(アクセス権限)の設定で弾かれている可能性が高いです。
##仮説
エラー文の3行目には「AWS HTTPエラー」と書かれています。
つまり疑うべきはAWSのパーミッションです。(今回はS3)
##S3(AWS)のパーミッション
S3のパーミッションは、バケットの「アクセス権限」というタブで設定できます。
画像のように上の二つのチェックを外します。
全部外してもいいですが、アクセス権限を緩めるということはそれだけセキュリティが脆くなるということなので、最低限に留めておくことに越したことはないでしょう。
したがって下の二つはブロックしたままにします。
ちなみに、下二つの選択肢にあるバケットポリシーとは「Access Policy Language (APL) を使用してストレージへのアクセス可否を定義するもの」です。どんなアクセスを許可し、どんなアクセスを禁止するかをコードで定義することができます。
アクセスポイントポリシーはそこから派生したもので、文字通りどこからのアクセスなら許可を通すかなどを決められるものです。(例えば、VPC内からのみアクセスを許可するなど)
いずれも今回は使っていない(特別な設定をしていない限りは使っていないはず)ので、ブロックしたままにします。
上二つの選択肢の違いは「新しい」と「任意の」の部分ですが、任意のだけを許可した場合はこれまで投稿した画像にアクセスはできますが、新規投稿ができなくなります。
したがって今回は上の二つを外します。
##ご挨拶
最後までご覧いただきありがとうございます。少しでも参考にして頂けたら嬉しいです。私自身プログラミング歴が約半年と短いため、至らない点も多いと思います。ご指摘などがございましたら、コメントにてご教示頂けたら幸いです。