S3にアップした画像が「403 (Forbidden)」エラーで表示されない

## 目的
LaravelでS3にアップした画像をサイトで表示する。

## 画像アップ処理

### パッケージをComposerでインストール

```
"aws/aws-sdk-php": "~3.0",
"league/flysystem-aws-s3-v3": "~1.0",
```
パフォーマンスを上げるため、絶対に必要なのはキャッシュアダプタ
"league/flysystem-cached-adapter": "~1.0",

### S3ドライバ設定

S3ドライバの設定情報は、config/filesystems.php設定ファイルに設定

```
// Default Filesystem Disk
'default' => env('FILESYSTEM_DRIVER', 'local'),

// Default Cloud Filesystem Disk
'cloud' => env('FILESYSTEM_CLOUD', 's3'),

// Filesystem Disks
'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_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION'),
        'bucket' => env('AWS_BUCKET'),
        'url' => env('AWS_URL'),
    ],
]
```

### envファイル

```
AWS_ACCESS_KEY_ID=アクセスキーID
AWS_SECRET_ACCESS_KEY=シークレットアクセスキー
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET=バケット名
AWS_URL=https://s3-ap-northeast-1.amazonaws.com/バケット名/
FILESYSTEM_DRIVER=s3
```

### LaravelのController

// ディスクインスタンス取得
use Illuminate\Support\Facades\Storage;

//  画像アップロード
保存したいファイルのパスを指定し、storeメソッドでアップロード
$path = request()->file('file')->store('tmp');
アップロードした画像を一時領域('tmp')に保存

// urlメソッドを使い、指定したファイルのURLを取得
'url' => Storage::url($path),
s3ドライバを使用している場合、完全なリモートURLを返す

### その他ファイル関連メソッド

// ファイル取得
$contents = Storage::get('file.jpg');

// ファイルが存在しているかを判定
$exists = Storage::disk('s3')->exists('file.jpg');

// ファイルのダウンロード
return Storage::download('file.jpg', $name, $headers);


## 画像表示
下記のURLで画像表示

```
img src="https://app-develop.s3.ap-northeast-1.amazonaws.com/Image/H5o2hmClZdGfH5s0d8DNxlkZs6Y8L1xUL0.jpeg
```

バケット名（app-develop　）
Amazon リソースネーム (ARN)　（arn:aws:s3:::app-develop）

画像表示で「403 (Forbidden)」エラーで表示されない
原因はバケットポリシーが公開状態になってない為

## バケットポリシー公開設定
下記のPolicy Generatorを使用し、jsonフォーマットのポリシー定義を記述する
http://awspolicygen.s3.amazonaws.com/policygen.html

![スクリーンショット 2020-11-05 11.45.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/14ecae60-297a-560c-069a-c84945f99ba0.png)

入力内容は下記である

```
・Principal ：　*
特定のアカウントに対して参照可能にする場合は下記：
・Principal ：　権限付与するAWSアカウントID

・AWS Service： Amazon S3

・Actions: s3:GetObject

・ARN:  arn:aws:s3:::app-develop/*

とし、Add Statementを押下。続けて

・Principal ：　*
特定のアカウントに対して参照可能にする場合は下記：
・Principal ：　権限付与するAWSアカウントID

・AWS Service： Amazon S3

・Actions: s3:ListBucket

・ARN:  arn:aws:s3:::app-develop
```

Statementが２つあるのは、GetObjectはバケット配下のオブジェクトに対する定義であり、ListBucketはバケットそのものに対する定義となるため

![スクリーンショット 2020-11-05 11.49.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/0b0b139a-52e4-ca9e-2057-c9d364edbe67.png)

```
{
  "Id": "Policy1604544585920",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1604544465312",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::app-develop/*",
      "Principal": "*"
    },
    {
      "Sid": "Stmt1604544535477",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::app-develop",
      "Principal": "*"
    }
  ]
}
```

Generate Policyを押下すると、ポリシー定義したjson記述が表示されるのでコピーする。

S3の画面にて、バケットのプロパティを表示し Permissions-> Edit bucket policyで上記jsonを貼り付けて saveする

![スクリーンショット 2020-11-05 11.49.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/eeb13837-9b31-d14f-aac5-0f01028d1f9a.png)


## 画像表示確認
下記のURLで画像確認

```
img src="https://app-develop.s3.ap-northeast-1.amazonaws.com/Image/H5o2hmClZdGfH5s0d8DNxlkZs6Y8L1xUL0.jpeg
```

エラーなく無事画像表示される〜〜