TECH PLAY

株式会社Re:Build

株式会社Re:Build の技術ブログ

61

※本記事は嘉数の個人ブログ( LaravelでS3へファイルをアップロード・参照する - けけずんセルフハッキング )からの転載になります 概要 LaravelでアップロードされたファイルをS3に保存・参照する。 ファイルアップロード時の処理は下図の通り、クライアントからLaravelを通ってS3に保存される。 ファイルを参照する際は下図の通り、Laravelが対象となるファイルのURLをS3から取得してページにリンクする。URLからS3上のファイルを参照するために、対象となるファイルはPublicに公開される必要がある。 環境 Laravel 5.5.36 Laravelが動作するEC2、ファイル保存・参照先となるS3 バケット は作成済みとする。 手順 AWS 側の操作 AWS コンソールへログインし、以下の操作を行う。 IAMユーザーの作成 サービス「IAM」からサイドバーの「ユーザー」をクリックし、続いて以下の操作を行う。 「ユーザーを追加」をクリックする 「ユーザー名」を入力する 「プログラムによるアクセス」にチェックを入れる 「次のステップ:アクセス権限」をクリックする 「ユーザーをグループに追加」を選択する 「次のステップ:確認」をクリックする 「ユーザーの作成」をクリックする ここでユーザの作成が完了する。このとき、作成したユーザーのセキュリティ認証情報が記述されたファイル( CSV )がダウンロード出来るので、ダウンロードしておく。 IAMユーザのアクセス権限を設定 サービス「IAM」からサイドバーの「ユーザー」をクリックし、続いて以下の操作を行う。 作成したユーザーをクリックする 「アクセス権限」タブを選択し、「インラインポリシー」をクリックする 「ビジュアルエディタ」タブにある項目を以下のように入力する 「サービスの選択」:S3 「アクション」: 「GetObject」にチェック 「PutObject」にチェック 「DeleteObject」にチェック 「PutObjectAcl」にチェック 「リソース」: 「指定」にチェック 「ARNの追加」から使用するS3 バケット のARNを入力 プレフィックス も指定するなら指定する 「Review policy」をクリックする 「名前」を入力する 「Create a policy」をクリックする ちなみに JSON は以下のようになる。 { " Version ": " 2012-10-17 ", " Statement ": [ { " Sid ": " VisualEditor0 ", " Effect ": " Allow ", " Action ": [ " s3:PutObject ", " s3:GetObject ", " s3:DeleteObject ", " s3:PutObjectAcl " ] , " Resource ": " arn:aws:s3:::mybucket/myprefix/* " } ] } Resource 要素の末尾に * がないと指定した プレフィックス (今回は myprefix )以下を操作する権限がないと言われるので注意! Laravel側の操作 パッケージをインストール Laravelプロジェクトフォルダ下で以下のコマンドを入力する。 $ composer require league/flysystem-aws-s3-v3 これによりLaravelの ファイルシステム でファイルの保存・参照先をS3に向けるためのパッケージがインストールされる。 .envを編集 .env ファイルに以下を追記する。 AWS_S3_KEY=[AWS S3接続用ユーザのAccess Key ID] AWS_S3_SECRET=[AWS S3接続用ユーザのSecret Key] AWS_S3_REGION=[AWS S3設置リージョン] AWS_S3_BUCKET=[AWS S3のバケット名] config/filesystems. php を編集 config/filesystems.php を以下のように編集する。 <?php return [ ' default ' => ' local ', ' cloud ' => ' s3 ', ' disks ' => [ ' local ' => [ ' driver ' => ' local ', ' root ' => storage_path ( ' app ' ) , ] , ' public ' => [ ' driver ' => ' local ', ' root ' => storage_path ( ' app/public ' ) , ' url ' => env ( ' APP_URL ' ) . ' /storage ', ' visibility ' => ' public ', ] , + ' s3 ' => [ + ' driver ' => ' s3 ', + ' key ' => env ( ' AWS_S3_KEY ' ) , + ' secret ' => env ( ' AWS_S3_SECRET ' ) , + ' region ' => env ( ' AWS_S3_REGION ' ) , + ' bucket ' => env ( ' AWS_S3_BUCKET ' ) , + ] , ] , ] ; Controllerの作成 以下のコマンドでControllerを作成する。 $ php artisan make:controller UploadContentController app/Http/Controllers/UploadContentController.php を以下のように編集する。 <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; class UploadContentController extends Controller { public function index () { return view ( ' upload ' ) ; } public function store ( Request $ request ) { $ this -> validate ( $ request , [ ' myfile ' => ' required|image ' ]) ; $ image = $ request -> file ( ' myfile ' ) ; /** * 自動生成されたファイル名が付与されてS3に保存される。 * 第三引数に'public'を付与しないと外部からアクセスできないので注意。 */ $ path = Storage :: disk ( ' s3 ' ) -> putFile ( ' myprefix ', $ image , ' public ' ) ; /* 上記と同じ */ // $path = $image->store('myprefix', 's3'); /* 名前を付与してS3に保存する */ // $filename = 'hoge.jpg'; // $path = Storage::disk('s3')->putFileAs('myprefix', $image, $filename, 'public'); /* ファイルパスから参照するURLを生成する */ $ url = Storage :: disk ( ' s3 ' ) -> url ( $ path ) ; return redirect () -> back () -> with ( ' s3url ', $ url ) ; } } Viewの作成 resources/views/upload.blade.php を作成し、以下のようにする。 <!DOCTYPE html> < html > < head > < meta charset = "utf-8" > < title > Upload S3 Test </ title > </ head > < h1 > S3アップロードテスト </ h1 > {!! Form::open(['url' = > '/upload', 'method' = > 'post', 'class' = > 'form', 'files' = > true]) !!} < div class = "form-group" > {!! Form::label('myfile', 'Upload a file') !!} {!! Form::file('myfile', null) !!} </ div > < div class = "form-group" > {!! Form::submit('Upload') !!} </ div > {!! Form::close() !!} @if (session('s3url')) < h1 > いまアップロードしたファイル </ h1 > < img src = "{{ session('s3url') }}" > @endif </ html > 考察 LaravelからS3に対してファイルのアップロード及びファイルの参照を行うことができた。Controller内でファイルアップロード時のS3の プレフィックス を指定している箇所があるが、毎回同じ プレフィックス を指定するの面倒くさいな。何かいい方法ないかな。 参考 Laravel 5.4でS3ファイルアップロード - Qiita Laravel 5.3 AWS S3にファイルをアップロード – ララジャパン
アバター