【问题标题】:Laravel s3 upload file with metadata using pre-signed urlLaravel s3使用预签名的url上传带有元数据的文件
【发布时间】:2022-04-28 08:42:51
【问题描述】:

我正在使用预签名的 url 实现 S3 文件上传和下载。我有一个 s3 存储桶(启用版本控制)和一个 AWS 用户,但我想根据我的哪些应用程序用户修改了文件来跟踪每个文件的历史记录。

我有一个版本化的 S3 存储桶,我的想法是我可以将元数据附加到每个文件以识别我的应用程序用户以及可能的其他数据。

这是我的代码:

    public function presignedUpload(Request $request)
    {
        $this->validate($request, [
            'name' => 'string|required'
        ]);

        $s3 = Storage::disk('s3');
        $client = $s3->getDriver()->getAdapter()->getClient();
        $expiry = "+10 minutes";


        $options = ['user-data' => 'user-meta-value'];

        $cmd = $client->getCommand('PutObject', [
            'Bucket' => \Config::get('filesystems.disks.s3.bucket'),
            'Key' => 'path/to/file/' . $request->name,
            'ACL' => 'public-read',
        ], $options);

        $request = $client->createPresignedRequest($cmd, $expiry);

        $presignedUrl = (string)$request->getUri();

        return response()->json(['url' => $presignedUrl], 201);
    }

我推断我可以从FilesystemAdapter::class 传递一个$options 数组。此代码确实上传了文件,但 AWS 中的元数据看起来是空的。

我的$options 数组格式是否错误?

感谢您对此的任何帮助。

【问题讨论】:

    标签: php laravel amazon-web-services amazon-s3


    【解决方案1】:

    元数据可以这样上传:

     public function presignedUpload(Request $request)
        {
            $this->validate($request, [
                'name' => 'string|required'
            ]);
    
            $s3 = Storage::disk('s3');
            $client = $s3->getDriver()->getAdapter()->getClient();
            $expiry = "+10 minutes";
    
    
            $options = ['user-data' => 'user-meta-value'];
    
            $cmd = $client->getCommand('PutObject', [
                'Bucket' => \Config::get('filesystems.disks.s3.bucket'),
                'Key' => 'path/to/file/' . $request->name,
                'ACL' => 'public-read',
                'Metadata' => $options,
            ]);
    
            $request = $client->createPresignedRequest($cmd, $expiry);
    
            $presignedUrl = (string)$request->getUri();
    
            return response()->json(['url' => $presignedUrl], 201);
        }
    

    【讨论】:

      【解决方案2】:

      选择的答案在 Laravel 9 之后不再起作用。Flysystem 建议您使用 S3 SDK 而不是 Storage 驱动程序。

      https://github.com/thephpleague/flysystem/issues/1423

      改用 S3 SDK 创建一个辞职的上传 URL。

          $uploadDisk = 's3';
      
          $s3Client = new S3Client([
              'credentials' => [
                  'key' => config('filesystems.disks.' . $uploadDisk . '.key'),
                  'secret' => config('filesystems.disks.' . $uploadDisk . '.secret'),
              ],
              'region' => config('filesystems.disks.' . $uploadDisk . '.region'),
              'version' => 'latest',
          ]);
          
          $s3Bucket = config('filesystems.disks.' . $uploadDisk . '.bucket');
          $s3Key = \Illuminate\Support\Str::uuid(); // your file name
          $s3Options = [];
          
          $command = $s3Client->getCommand('PutObject', [
              'Bucket' => $s3Bucket,
              'Key' => $s3Key,
              'MetaData' => $s3Options,
          ]);
          
          $request = $s3Client->createPresignedRequest($command, '+20 minutes');
          
          $url = (string) $request->getUri();
      

      【讨论】:

        猜你喜欢
        • 2019-05-08
        • 1970-01-01
        • 1970-01-01
        • 2021-03-08
        • 1970-01-01
        • 2020-09-30
        • 2014-10-27
        • 2015-10-13
        相关资源
        最近更新 更多