确保S3中的随机密钥名称,同时保留用户的原始文件名

时间:2018-01-27 00:05:12

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

以前,我使用PHP(并运行Apache)在服务器上本地存储客户端文件。他们会上传文件,每个文件都会被赋予一个以pdf / jpg文件扩展名结尾的随机字符串。原始文件名将与随机名称一起保存在数据库中,以便在用户需要文件时将它们链接在一起。

我想转换到在S3中的私有存储桶上存储文件。我首先看到的是这个article,它表示给对象键一个唯一的名称,但我看到的所有示例都只是将用户的文件名放在那里。 / p>

这是一个问题,因为如果用户存储test.pdf而另一个用户上传完全不同的test.pdf,则无法上传。另一个问题是,如果我像以前一样使用随机文件名,然后用户从预先签名的请求中获取文件,那么他们将访问一个通过一些随机字符串命名的文件而不是他们认为的文件上传。

我应该做些什么来分离用户的文件,同时将原始文件名保留在s3上?

2 个答案:

答案 0 :(得分:2)

就个人而言,我完全按照你在第一个例子中描述的那样做。 S3文件获取为存储桶中的文件名生成的UUID,包括原始文件名在内的所有元数据都在数据库中。

我甚至不打算给S3文件一个扩展名。

扩展我的评论以及有关如何阅读文件的问题;

我将Laravel与Intervention\Image (site)一起使用。

附件控制器的我的GET端点在我的模型中返回此功能:

/**
 * Gets an image from Amazon and returns it
 * @param boolean $thumb
 * @return null|Image
 */
public function output($thumb = false)
{
    if ($this->s3_filename === null) {
        return null;
    }
    // Grab the image from S3
    $this->image = $this->s3->get('/' . $this->getPath() . '/' . ($thumb ? 'thumb/' : '') . $this->s3_filename);
    if ($this->image === null) {
        return null;
    }
    return Image::make($this->image)->response()->withHeaders([
        'content-disposition' => 'inline; filename="' . ($thumb ? 'thumb_' : '') . $this->filename . '"',
    ]);
}

答案 1 :(得分:1)

考虑使用存储桶/文件夹怎么样?

存储桶需要具有唯一的名称(跨所有AWS ...不确定是否已更改)。但是其中的文件夹很好。

但除此之外:

myBucket/
    user1/
        test.pdf
    user2/
        test.pdf

在存储桶AFAIK中拥有目录不需要额外费用,所以你应该做得很好。

您也可以使用UUID而不是user1,并在某处将用户名映射到UUID以生成存储桶/文件夹路径。