在 Laravel 中使用 AWS S3 存储
发布时间 作者 Shane D Rosenthal
我知道,我知道!我也经历过,相信我。AWS 仪表盘可能令人望而生畏、令人困惑,似乎过于复杂,无法满足您的需求。与其他流行的资源相比,很容易完全放弃 AWS 并选择其他方案。
但是,世界上一流公司选择 AWS 来构建 Web 服务是有原因的。像 Twitch、LinkedIn、Facebook 这样的公司,甚至 Netflix 的所有休闲电影都是通过 AWS 传输的。这是有充分理由的。
我无法在一篇文章中教授所有 AWS 内容,但我可以稍微揭开仪表盘的神秘面纱,向您展示如何浏览并最终在 Laravel 应用中实现 S3 存储桶。
先决条件
在尝试本文中的任何操作之前,我要求您具备以下两项内容。
- 一个 AWS 账户。
- 一个 Laravel 项目,已安装
Flyststem S3
包,安装命令如下
composer require league/flysystem-aws-s3-v3 "^3.0" --with-all-dependencies
IAM 身份与访问管理
与大多数 AWS 中看起来令人困惑的名称一样,这个实际上很简单。IAM 代表“身份与访问管理”。
我们需要从这里开始,创建一个组和一个用户,并获取您的访问密钥和密钥。来吧,一步一步来。
用户组
- 在顶部的搜索栏中,输入“IAM”,然后点击 IAM 服务。
- 在左侧边栏中,点击“用户组”。
- 点击“创建组”按钮。
- 为该组创建一个名称,我将我的命名为“S3FullAccess”,该组中的所有用户都将拥有完全访问权限,可以对我的所有 S3 存储桶执行任何操作,但他们只能访问 S3 存储桶进行更改。
- 向下滚动,在“附加权限策略”中,搜索“S3”。这里的搜索栏有点不灵敏,只需按回车键,您将看到列表更新。
- 选中“AmazonS3FullAccess”旁边的框,然后点击底部的“创建组”按钮。
创建用户
- 接下来,点击左侧边栏中的“用户”。
- 点击“创建用户”,并为用户提供一个名称。现在名称可以是任何您想要的,通常我会为我的每个应用创建一个用户,并根据应用名称进行命名。
- **不要**选中“授予用户 AWS 控制台访问权限”复选框,除非您知道自己在做什么。本质上,这将允许我们的用户登录 AWS 并拥有 API 访问权限,而这并非本演示的目标。
- 点击“下一步”。现在我们将把此用户添加到我们刚刚创建的组中,选中该组旁边的复选框,然后点击“下一步”。
- 如果您愿意,可以为您的用户添加“标签”,我通常会跳过这些步骤。点击“创建用户”。
获取密钥和密钥
- 下一个屏幕将显示所有用户列表,点击您刚刚创建的用户。
- 点击“安全凭据”选项卡,向下滚动到“访问密钥”部分。
- 点击“创建访问密钥”。
- 在本教程中,我们创建的用户本质上是一个“第三方服务”,选择它,选中底部的确认框,然后点击“下一步”。
- 我跳过描述标签。每个用户可以拥有多个访问密钥(最多 2 个),您可以在此处对其进行标记(如果您愿意)。
- 点击“创建访问密钥”。在下一页,您将看到您的访问密钥,并且可以显示或复制您的密钥。您将需要这两个值,复制它们并将其粘贴到 Laravel 的
.env
文件中。
创建存储桶
好的,“S3” - 这是另一个令人困惑的 AWS 名称,对吧?S3 - 简称为简单存储服务,3 个 S = S3。就是这样。我相信您想出的变量名称比这个更糟糕 :D。所有放入存储桶的内容都是“对象”,我可能更倾向于使用“对象”而不是图片、视频等,因为任何内容都可以放入存储桶。存储桶简而言之就是对象的容器。
开始吧!
创建存储桶
- 在搜索栏中输入“s3”,然后选择“S3”。
- 点击“创建存储桶”按钮。在下一个屏幕上,我们将指定几个可以在以后编辑的选项,但存储桶名称除外。
- 此外,请务必记下“AWS 区域”,您需要在
.env
文件中使用它。
A Note about Bucket names: Bucket names are unique per region.The `us-east-1` region is closes to where I live and the one I typically use,but so do a LOT of people. The bucket name "Laravel" for example will notbe available there because someone else created it first. Choose yourbucket name carefully.
- 向下滚动,在“对象所有权”部分的“ACL 启用”部分选中单选按钮。
- 选择“对象写入器”。
- 取消选中“阻止所有公共访问”,并选中确认框。
- 我将保持版本控制禁用,无标签... 我将保留其他默认设置,并点击“创建存储桶”。
更新存储桶策略和 CORS
- 下一个屏幕应该显示存储桶列表,点击您刚刚创建的存储桶。
- 点击“权限”选项卡。
- 在“存储桶策略”部分,点击“编辑”按钮,粘贴以下代码,但请确保用您的存储桶名称更新它,然后点击“保存更改”。
{ "Version": "2012-10-17", "Id": "Policy1692807538499", "Statement": [ { "Sid": "Stmt1692807537432", "Effect": "Allow", "Principal": "*", "Action": "s3:*", "Resource": "arn:aws:s3:::laravelonlinebucket" } ]}
- 您可以详细了解如何控制谁以及哪些内容可以访问您的存储桶对象,此语句将允许任何“主体”或实体对我们的存储桶执行任何操作。随着您学习的深入,您可以对这些语句进行更严格的限制。
- 滚动到“访问控制列表 (ACL)”部分,然后点击“编辑”按钮。
- 选中“所有人(公共访问)”旁边的“列出”和“读取”复选框,并选中底部的确认框,然后点击“保存更改”。
- 向下滚动到“跨源资源共享 (CORS)”部分,点击“编辑”按钮,然后粘贴以下代码
[ { "AllowedHeaders": [], "AllowedMethods": [ "GET", "PUT", "POST", "DELETE" ], "AllowedOrigins": [ "*" ] }]
- 在该 JSON 的“AllowedOrigins”部分,我们允许所有来源,这意味着任何域都可以访问此存储桶中的对象。如果您想将它限制为特定域,您可以在此处进行调整。
- 点击“对象”选项卡。在将一些对象推送到存储桶后,我们将刷新此部分。
- 让我们返回到 Laravel 应用,并相应地更新
.env
文件,设置您的存储桶名称、区域、URL 等,如下所示。
AWS_ACCESS_KEY_ID=AKIA35DMCR3BAIFEVVMPAWS_SECRET_ACCESS_KEY=YMrG4Tw6UQ0HHKU/ByvhBxuF56jKhgTJfBwHUkVRAWS_DEFAULT_REGION=us-east-1AWS_BUCKET=noonewillevergetthisbucketnameAWS_URL="https://noonewillevergetthisbucketname.s3.amazonaws.com/"AWS_USE_PATH_STYLE_ENDPOINT=true
外观
本教程**不是** Laravel 存储课程。但是,我们必须看到我们刚刚所做工作的益处并测试一下。我将采用一种非常简单的做法来将对象推送到存储桶中,并从 Web 路由函数中执行所有操作 - YOLO!
存储磁盘
- 回到你的 Laravel 应用中,前往
config/filesystems.php
文件。 - 你可以使用这里已经设置的
S3
磁盘,并进行一些调整。但是,通常我的应用程序会发布不同类型的文件,我希望将它们组织到存储桶中的不同目录中。例如,“发票”目录和“个人资料图片”目录。我将在此处创建两个磁盘并对其进行适当配置。 - 粘贴以下代码,并根据你的用例进行更新
'invoices' => [ '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'), 'endpoint' => env('PROFILE_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 'visibility' => 'public', 'root' => 'invoices'],,'profile-photos' => [ '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'), 'endpoint' => env('PROFILE_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 'visibility' => 'public', 'root' => 'profile-photos'],
- 注意“root”,它告诉 S3 使用每个磁盘时将文件放在哪个目录中。
演示时间
- 在我的
storage/app
目录中存储着一个名为“hero.png”的图像,我将用于本演示。 - 下面的代码从我的存储目录中获取原始图像数据,然后将其上传到指定的磁盘/目录中,该目录返回路径,使用
Storage
的url
函数,将路径传递进去,我们就可以得到该图像的完整 URL!
Route::get('buckets', function(){ $disk = 'profile-photos'; $heroImage = Storage::get('hero.png'); $uploadedPath = Storage::disk($disk)->put('hero.png', $heroImage); return Storage::disk($disk)->url($uploadedPath);});
- 在浏览器中访问此路由将得到:https://noonewillevergetthisbucketname.s3.amazonaws.com/profile-photos/hero.png。试试看,查看一下我用Midjourney制作的这幅很棒的图片。
- 如果我们回到 AWS 中的存储桶对象并刷新,我们应该看到
profile-photos
目录和其中的hero.png
文件。 - 如果我们在函数中更换磁盘,再次刷新 S3 对象,我们将看到为我们的发票创建了一个不同的目录。
Route::get('buckets', function(){ $disk = 'invoices'; $heroImage = Storage::get('hero.png'); $uploadedPath = Storage::disk($disk)->put('hero.png', $heroImage); return Storage::disk($disk)->url($uploadedPath);});
- 你可以继续使用你所知和喜爱的所有Laravel 存储方法,并利用 AWS S3 存储桶背后的强大功能。
还不错吧?
所以你已经体验到在 AWS 中可以做些什么。如果我知道我的一些对象需要在我的存储桶中“高度可用”,这意味着它**必须**在世界各地快速可用,我会做的一件事是利用 Cloudfront,它会将存储桶或存储桶中目录中的所有文件分发到世界各地的亚马逊服务器。这样,当日本的人请求文件时,它就不会从弗吉尼亚州一路跳到那里。尝试一下,多做实验,试试看!
你可能会成为这方面的专家,然后涨工资 😉!
我是一个科技狂热分子、家庭男人、社区领袖、飞行员和音乐家。从 80 年代中期开始,我就一直拆卸东西看看它们是如何工作的,并试图将它们重新组装起来,有时比以前更好。在此过程中,我遇到了我生命中的挚爱,组建了一个家庭,在领导和教育他人方面找到了目标,最近还成为了一名飞行员。我对飞行充满热情,乐于与周围的人分享世界,并且能够参加一些现场金属音乐表演。
展望未来,我打算拥有自己的飞机,保持仪表等级,继续教育和指导我们的年轻人,发展我的 YouTube 频道和粉丝,并分享我的热情,以影响我所能影响的人。