前提・実現したいこと
LaravelでAWS S3に画像をアップロードする機能を実装しています。
以下のようなエラーが発生しました。
- The bucket does not allow ACLs
- 400 Bad Request
原因がわかる方がいましたら、ぜひ教えていただきたいです。
発生している問題・エラーメッセージ
Error executing "PutObject" on "https://laravel-vue-app-to-do-sengen-backet.s3.ap-northeast-1.amazonaws.com/image/hbzqDxchRSed2TNRlDXeKe5gIfAmMaWQoDrr9JKu.jpg"; AWS HTTP error: Client error: `PUT https://laravel-vue-app-to-do-sengen-backet.s3.ap-northeast-1.amazonaws.com/image/hbzqDxchRSed2TNRlDXeKe5gIfAmMaWQoDrr9JKu.jpg` resulted in a `400 Bad Request` response: <?xml version="1.0" encoding="UTF-8"?> <Error><Code>AccessControlListNotSupported</Code><Message>The bucket does not all (truncated...) AccessControlListNotSupported (client): The bucket does not allow ACLs - <?xml version="1.0" encoding="UTF-8"?> <Error><Code>AccessControlListNotSupported</Code><Message>The bucket does not allow ACLs</Message><RequestId>HYC4E3ZWN7X4JMJ5</RequestId><HostId>TqhxfWxKiliOEGYh5lr/gM27uQXfyS8ZgYc5E11Lp6uig72kw/alhA+xZyFkeqegtSHcYXEEuOg=</HostId></Error>
該当のソースコード
.env(実際には入力されています)
AWS_ACCESS_KEY_ID= csvの認証情報に記載されているAccess key ID AWS_SECRET_ACCESS_KEY= csvの認証情報に記載されているSecret access key AWS_DEFAULT_REGION=ap-northeast-1 (リージョンをアジアパシフィック東京で作成したため) AWS_BUCKET= 作成したバケット名
app/Http/Controllers/UserController.php
PHP
<?php namespace App\Http\Controllers; // use App\Http\Requests\UserRequest; use App\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Validator; class UserController extends Controller { //略 //プロフィール編集画面 public function edit(string $name) { $user = User::where('name', $name)->first(); return view('users.edit', ['user' => $user]); } //プロフィール編集処理 public function update(Request $request, string $name) { $user = User::where('name', $name)->first(); $allRequest = $request->all(); // $profileImage = $request->file('image'); // dd($profileImage); // if ($profileImage) { // $allRequest['image'] = $this->saveProfileImage($profileImage, $user->id); // } //s3アップロード開始 $image = $request->file('image'); // バケットの`myprefix`フォルダへアップロード $path = Storage::disk('s3')->putFile('image', $image, 'public'); // アップロードした画像のフルパスを取得 $user->image = Storage::disk('s3')->url($path); $user->fill($allRequest)->save(); return redirect()->route('users.show', ["name" => $user->name]); } //略 }
database/migrations/2014_10_12_000000_create_users_table.php
PHP
public function up() { Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name')->unique(); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('twitter_id')->nullable(); $table->string('password')->nullable(); $table->string('image')->nullable(); $table->rememberToken(); $table->timestamps(); }); }
resources/views/users/edit.blade.php
PHP
<form action="{{ route('users.update', ['name' => $user->name]) }}" method="POST" enctype="multipart/form-data"> @method('PATCH') @csrf {{-- 編集フォーム --}} <label for="image"> <img src="{{ asset('storage/'.$user->image) }}" id="img" class="img-fuild rounded-circle" width="80" height="80"> <input type="file" id="image" name="image" onchange="previewImage(this);" class="d-none"> </label> <div class="md-form col-lg-6 col-md-7 col-sm-8 col-xs-10 mx-auto"> <label for="name">ユーザー名</label> <input type="text" class="form-control" id="name" name="name" required value="{{ $user->name }}"> <small>3〜15文字で入力してください</small> </div> <div class="md-form col-lg-6 col-md-7 col-sm-8 col-xs-10 mx-auto"> <label for="email">メールアドレス</label> <input type="text" class="form-control" id="email" name="email" required value="{{ $user->email }}"> </div> <button type="submit" class="btn btn-block cyan darken-3 text-white col-lg-8 col-md-9 col-sm-10 col-xs-12 mx-auto mt-5 mb-5 waves-effect"> 更新する </button> </form>
S3 バケットポリシー
{ "Version": "2012-10-17", "Id": "Policy1640118455749", "Statement": [ { "Sid": "Stmt1640118449406", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::580365198874:user/laravel-vue-app-to-do-sengen" }, "Action": [ "s3:ListBucket", "s3:GetObject", "s3:GetObjectAcl", "s3:PutObject", "s3:PutObjectAcl", "s3:ReplicateObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::laravel-vue-app-to-do-sengen-backet", "arn:aws:s3:::laravel-vue-app-to-do-sengen-backet/*" ] } ] }
routes/web.php
PHP
//ユーザーページ表示 Route::prefix('users')->name('users.')->group(function () { Route::get('/{name}', 'UserController@show')->name('show'); //プロフィール編集画面 Route::get('/{name}/edit', 'UserController@edit')->name('edit'); //プロフィール編集処理 Route::patch('/{name}/update', 'UserController@update')->name('update'); Route::get('/{name}/likes', 'UserController@likes')->name('likes'); Route::get('/{name}/followings', 'UserController@followings')->name('followings'); Route::get('/{name}/followers', 'UserController@followers')->name('followers'); Route::middleware('auth')->group(function () { Route::put('/{name}/follow', 'UserController@follow')->name('follow'); Route::delete('/{name}/follow', 'UserController@unfollow')->name('unfollow'); }); });
app/User.php
PHP
protected $fillable = [ 'name', 'email', 'password', 'twitter_id', 'image', ];
試したこと
- 環境変数の見直し
- バケットポリシーの見直し
補足情報(FW/ツールのバージョンなど)
Laravel 6.2
PHP 7.4.25
composer 2.1.12
node 16.13
まだ回答がついていません
会員登録して回答してみよう