はじめに
よくあるファイルアップロードの仕組みをLaravelとS3で作ってみたいと思います
前提
- Laravel version 5.6 のプロジェクトは作成済み
- AWSアカウントは作成済み
S3用のIAMを作成
まずはAWSのコンソールの右上から、自分のアカウントをクリックしアコーディオンを開き、「My Security Credentisals」をクリック
遷移したら、左側のメニューから「Users」をクリック
遷移したら、「Add User」をクリック
遷移したら、「User name」に適当な名前を入力し、「Select AWS access type」は「Programmatic access」を選択し、「Next: Permissions」をクリック
遷移したら、「Attach existing policies directly」をクリック
検索画面が表示されるので、S3を検索し、「AmazonS3FullAccess」にチェックを入れ、「Next: Review」をクリック
確認画面が表示されるので、「Create User」をクリック
最後に、Access key IDとSecret access keyが表示されるので、必ずメモすること!
メモしたら「Close」をクリックして、S3のアカウント作成は完了です
Bucketの作成
アカウントを作成したら、次はS3でBucketを作成します
S3の画面から、「Create bucket」をクリック
モーダルが表示されるので、「Bucket name」に適当な名前を入力し、Regionは「Asia Pacific(Tokyo)」を選択し、「Next」をクリック
遷移後、オプションを設定するモーダルが表示されます
設定系は要件によりけりですが、もちろん全てオフでも大丈夫です
簡単に各オプションの説明を書いておきます
「Versioning」は保存するファイルを上書きする際に以前のファイルを保持しておくオプションで、誤って上書きして以前のファイルを削除してしまった時に便利なオプションです
「Server access logging」はbucket内の操作に対してログを取ってくれるオプションです
「Tags」はbucketに任意のタグを割り当てることができ、コスト配分レポートなどで利用できるオプションです
「Object-level logging」はオブジェクト毎の操作に対してログを取ってくれるオプションです(Server access loggingとイマイチ違いはわからなかった)
「Default encryption」はデフォルトでアップロードするファイルを暗号化するオプションです
「CloudWatch request metrics」はほぼリアルタイムなメトリクスオプションです
遷移後、bucketに対してAWSアカウントを紐づけする画面になります
デフォルトで自分のアカウントが入っています
特に他のアカウントを紐づけする必要がなければ、「Next」をクリック
遷移後、プレビューが表示され問題なければ「Create bucket」をクリックし完了
LaravelからS3の利用
パッケージのインストール
Larave公式が言っている、s3用のパッケージをインストールする
composer require league/flysystem-aws-s3-v3
S3の環境情報を登録
.envファイルに下記情報を追記する
AWS_ACCESS_KEY_ID= 上記手順でユーザーを作成した際に表示されたAccess key ID
AWS_SECRET_ACCESS_KEY= 上記手順でユーザーを作成した際に表示されたSecret access key
AWS_DEFAULT_REGION=ap-northeast-1 (東京リージョンで作成したため)
AWS_BUCKET= 上記手順で作成したbucket名
アップロード
HTMLの作成
<form action="/upload" method="post" enctype="multipart/form-data">
{{ csrf_field() }}
<input type="file" name="file">
<button type="submit">保存</button>
</form>
Controllerの作成
public function upload(Request $request)
{
$file = $request->file('file');
// 第一引数はディレクトリの指定
// 第二引数はファイル
// 第三引数はpublickを指定することで、URLによるアクセスが可能となる
$path = Storage::disk('s3')->putFile('/', $file, 'public');
// hogeディレクトリにアップロード
// $path = Storage::disk('s3')->putFile('/hoge', $file, 'public');
// ファイル名を指定する場合はputFileAsを利用する
// $path = Storage::disk('s3')->putFileAs('/', $file, 'hoge.jpg', 'public');
return redirect('/');
}
結果
ファイルの表示
Controllerの作成
public function disp()
{
$path = Storage::disk('s3')->url('hoge.jpg');
return view('disp', compact('path'));
}
HTMLの作成
<img src="{{$path}}">
さいごに
思ったより簡単でした!
毎回s3を指定するのはめんどくさいなと、、、
S3用に継承してClass作るのが正解なのだろうか?