【发布时间】:2020-12-02 01:54:32
【问题描述】:
我有一个 AWS S3 存储桶来存储 laravel 应用程序的公共和私有文件的组合,如下所示:
AWS 存储桶和文件夹:
myapp
|____private
|____public
在我的刀片文件中,图像显示如下:
<img src="http://myapp.com/files/10"/>
这是我的路线:
Route::get('files/{id}', 'FileController@show');
这是我显示和上传文件的控制器方法:
public function show(Request $request, $id)
{
$file = \App\File::findOrFail($id);
$user = auth()->check() ? auth()->user() : new User;
$this->authorizeForUser($user, 'show', $file);
return Image::make(Storage::disk('s3')->get($file->path))->response();
}
public function store(FileRequest $request)
{
$file = $request->file('file');
$fileType = strtolower($request->input('file_type'));
$filePath = $fileType . '/' . Str::random(40) . '.' . $file->getClientOriginalExtension();
$user = auth()->user();
DB::beginTransaction();
try
{
$this->authorizeForUser($user, 'store', \App\File::class);
$newFile = \App\File::create([
"name" => $file->getClientOriginalName(),
"path" => $filePath,
"size" => $file->getSize(),
"mime_type" => $file->getMimeType(),
"type" => $fileType,
"user_id" => $user->id
]);
$image = Image::make($file->getRealPath())->resize(360, 180);
Storage::disk('s3')->put($filePath, $image->stream());
$content = "<textarea data-type=\"application/json\">{\"ok\": true, \"message\": \"Success\", \"path\": \"" . $newFile->path . "\", \"id\": \"" . $newFile->id . "\", \"name\": \"" . $newFile->name . "\" }</textarea>";
DB::commit();
} catch (\Exception $e)
{
DB::rollback();
$error = 'There was a problem uploading your file';
$content = "<textarea data-type=\"application/json\">{\"ok\": false, \"message\": \"" . $error . "\" }</textarea>";
}
return response($content);
}
这是经过身份验证的用户可以访问公共和私人文件而访客用户可以访问的文件策略 只访问公共文件:
public function show(User $user, File $file)
{
if ($file->type == 'public' || (!is_null($user->getKey()) && $file->type == 'private'))
return true;
}
}
我想添加缓存支持,因为即使是少数应用程序用户也会在 AWS S3 上产生数百甚至数千个 GET 请求。在存储桶为私有(即只能通过 IAM 用户访问)的情况下,如何缓存文件以降低 S3 成本?
我已经阅读了一些建议使用 cloudfront 的帖子,但这不只是增加了额外的成本,我如何使用上面的控制器方法实现 cloudfront,并且存储桶在根级别是私有的?
使用 laravel 文件缓存会是一个合适的选择吗?
我很想知道我可以在 S3 和 laravel 中使用哪些技术,最好是提供一些指导步骤和代码。
附言。我已经看过下面的帖子了。 Laravel AWS S3 Storage image cache
【问题讨论】:
-
您是否考虑过像 Cloudflare 这样的非 AWS 解决方案?
-
@Parsifal 在 cloudflare 上我将文件存储在哪里?另外,没有开箱即用的 laravel api 来使用 cloudflare 作为存储?
-
CloudFlare 是一个 CDN:它位于您的应用程序之外,并缓存已交付的文件。当用户第一次检索文件时,它来自您的站点。当该用户再次检索文件时,它来自 Cloudflare 缓存。
-
在您的情况下,这可能不合适,因为您正在授权所有图像请求。您当然可以通过更改文件名以包含用户令牌来使它们在每个用户的基础上可缓存,但这只有在同一个用户多次加载图像时才有帮助(在这种情况下,基于浏览器的缓存可以完成这项工作) .
标签: laravel amazon-web-services amazon-s3 caching amazon-cloudfront