我的symfony 5.4项目使用aws_s3+flysystem+liip_imagine。
在aws_s3中,我有一个PRIVATE bucket:"myBucket";包含3个子文件夹:
- 文档
- 照片
- 媒体
和IAM许可
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:DeleteObject",
"s3:GetObjectAcl",
"s3:PutObjectAcl",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::mybucket/*"
]
我的设置:请参阅:https://github.com/liip/LiipImagineBundle/issues/823
Service.yaml
...
parameters:
uploads_base_url: '%env(AWS_S3_UPLOAD_BASE_URL)%'
services :
AwsS3S3Client:
arguments:
-
version: '2006-03-01'
region: '%env(AWS_S3_ACCESS_REGION)%'
credentials:
key: '%env(AWS_S3_ACCESS_ID)%'
secret: '%env(AWS_S3_ACCESS_SECRET)%'
oneup_flysystem.yaml
...
adapters:
aws_s3_adapter:
awss3v3:
client : AwsS3S3Client
bucket: '%env(AWS_S3_BUCKET_NAME)%'
options:
ACL: bucket-owner-full-control
filesystems:
aws_s3_system:
adapter: aws_s3_adapter
lipp_imagine.yaml
# https://symfony.com/bundles/LiipImagineBundle/current/cache-resolver/aws_s3.html
# I do not understand everything
...
driver: "gd"
loaders:
aws_s3_loader:
flysystem:
filesystem_service: oneup_flysystem.aws_s3_system_filesystem
data_loader: aws_s3_loader
resolvers:
aws_s3_resolver:
flysystem:
filesystem_service: oneup_flysystem.aws_s3_system_filesystem
root_url: '%uploads_base_url%'
cache_prefix: media/cache
cache: aws_s3_resolver
filter_sets:
squared_thumbnail_small:
quality: 70
filters:
thumbnail:
size: [50, 50]
mode: outbound
树枝
# call twig_function assetPresigned
<a href="{{ assetPresigned('photos', player.photoFilename) }}" target="_blank">
<img src="{{ assetPresigned('photos', player.photoFilename ) | imagine_filter('squared_thumbnail_small') }}" alt="photo">
</a>
FileUploadService.php
public function assetPresigned(string $folder, string $filename): string
{
$command = $this->s3Client->getCommand('GetObject', [
'Bucket' => $this->awsS3BucketName,
'Key' => $folder.'/'.$filename,
]);
// RETURN PRESIGNED URL
$urlPresigned = $this->s3Client->createPresignedRequest($command, '+5 minutes');
return ((string) $urlPresigned->getUri());
}
第1位:我的问题是;squared_thumbnail_small";过滤器重写url,删除预先签名的
结果在树枝:
- href:图像显示在单击时,因为url是预签名的
- img:url失去签名,因此不显示
nb:它是liip_imagine via"imagine_filter('squared_tumbnail_small(,它在mybucket/media中创建缩略图。在这个阶段,缩略图还没有出现在mybucket/media中,因为它还没有显示
问题:如何正确配置我的代码,使筛选器不会删除预签名?
这是我尝试过的
FileUploadService.php-
namespace AppService;
...
public function assetPresigned(string $folder, string $filename): string
{
# call ImagineFilterService.php
$this->imagineFilter->filter($folder.'/'.$filename);
# ...
$command....
}
ImagineFilterService.php
namespace AppService;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentHttpFoundationRedirectResponse;
use LiipImagineBundleImagineCacheCacheManager;
use LiipImagineBundleImagineDataDataManager;
use LiipImagineBundleImagineFilterFilterManager;
use AppServiceFileUploadService;
# https://symfony.com/bundles/LiipImagineBundle/current/filters.html#dynamic-filters
# I tried to create a filter dynamically based on this documentation
Class ImagineFilterService
public function filter($path)
{
$filter = 'squared_thumbnail_small';
# if photo is not stored in myBucket/media then you save it by applying the filter?
if (!$this->cacheManager->isStored($path, $filter)) {
$binary = $this->dataManager->find($filter, $path);
$filteredBinary = $this->filterManager->applyFilter($binary, $filter);
# In this method, I pass in parameter the resolver
$this->cacheManager->store($filteredBinary, $path, $filter, 'aws_s3_resolver');
}
// ERROR 403!!!
return $this->cacheManager->resolve($path, $filter);
}
我现在恢复已经存储在myBucket/media(ok(中的缩略图
但在myBucket/media中保存新缩略图时,我出现了403错误。
AWS HTTP错误:客户端错误:PUT resulted in a
403 Forbidden`响应:拒绝访问
所以我失去了证书。
这对我来说很复杂,准确的答案(参见一段代码(会对我有很大帮助。我不知道我错在哪里了。我已经被卡住好几天了
谢谢你的帮助。
嘿,我找到了一个保留签名url的解决方案。我不知道我们是否可以做得更简单,但它有效。
包裹
- "liip/想象捆绑包":"2.10">
- "联盟/飞行系统-aws-s3-v3":"3.13">
- "联盟/飞行系统捆绑包":"3.1〃
- "oneup/flysystem束":"4.6〃
S3Client的示例
//service.yaml
AwsS3S3Client:
arguments:
- endpoint: '%env(IONOS_S3_ENDPOINT)%'
version: '%env(IONOS_S3_VERSION)%'
region: '%env(IONOS_S3_REGION)%'
credentials:
key: '%env(IONOS_S3_ACCESS_ID)%'
secret: '%env(IONOS_S3_ACCESS_SECRET)%'
我有一个端点论点,因为我使用ionos作为s3。
配置您的适配器及其文件系统,以便在其中加载您的映像
//oneup_flysystem.yaml
oneup_flysystem:
adapters:
user_adapter:
awss3v3:
client: AwsS3S3Client
bucket: '%env(IONOS_S3_BUCKET_NAME)%'
prefix: "users"
user_thumbnail_adapter:
awss3v3:
client: AwsS3S3Client
bucket: '%env(IONOS_S3_BUCKET_NAME)%'
prefix: "cache/user_thumbnail"
user_medium_adapter:
awss3v3:
client: AwsS3S3Client
bucket: '%env(IONOS_S3_BUCKET_NAME)%'
prefix: "cache/user_medium"
filesystems:
user:
adapter: user_adapter
mount: user
userThumbnail:
adapter: user_thumbnail_adapter
mount: userThumbnail
userMedium:
adapter: user_medium_adapter
mount: userMedium
我有一个带有user_adapter的用户文件系统链接,可以将我的映像加载到我的bucket的这个文件夹中。
其他(如userThumbnail和userMedium(将用于liip_imagine过滤器自动生成的缓存图像。我只为下一步需要获得裁剪图像时配置了它们
配置liip_imagine
liip_imagine:
driver: "gd"
loaders:
user_loader:
flysystem:
filesystem_service: oneup_flysystem.user_filesystem
resolvers:
aws_s3_resolver:
aws_s3:
bucket: '%env(IONOS_S3_BUCKET_NAME)%'
client_config:
credentials:
key: '%env(IONOS_S3_ACCESS_ID)%'
secret: '%env(IONOS_S3_ACCESS_SECRET)%'
endpoint: '%env(IONOS_S3_ENDPOINT)%'
region: '%env(IONOS_S3_REGION)%'
version: '%env(IONOS_S3_VERSION)%'
acl: private
cache_prefix: cache
get_options:
Scheme: 'https'
put_options:
CacheControl: 'max-age=86400'
cache: aws_s3_resolver
filter_sets:
cache: ~
user_thumbnail:
cache: aws_s3_resolver
quality: 75
filters:
thumbnail: { size: [ 130, 130 ], mode: outbound }
data_loader: user_loader
user_medium:
cache: aws_s3_resolver
quality: 75
filters:
thumbnail: { size: [ 302, 180 ], mode: outbound }
data_loader: user_loader
为了将我的文件作为缓存文件夹中的私有文件,我为aws_s3_resolver配置了私有的acl
现在,当我想转到liip_imagine生成的url时,我得到了拒绝访问。为了最终获得资源,我需要更改liip_imagine使用签名url进行的重定向。因此,我创建了一个订阅者来捕捉解析后事件。
使用事件liip_imagine.post_resolve配置订阅者
namespace AppEventSubscriber;
use AppEntityMedia;
use AppEnumMediaFilterEnum;
use AppRepositoryMediaRepository;
use LeagueFlysystemFilesystemOperator;
use LiipImagineBundleEventsCacheResolveEvent;
use SymfonyComponentEventDispatcherEventSubscriberInterface;
class LiipImagineFilterSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly MediaRepository $mediaRepository,
private readonly FilesystemOperator $userThumbnailFilesystem,
private readonly FilesystemOperator $userMediumFilesystem
)
{
}
public function onPostResolve(CacheResolveEvent $event): void
{
$media = $this->mediaRepository->findOneBy(['photo' => $event->getPath()]);
$filter = $event->getFilter();
if ($media instanceof Media) {
$date = new DateTime();
$date = $date->add(new DateInterval('PT10M'));
if ($filter === MediaFilterEnum::USER_THUMBNAIL->value) {
$path = $this->userThumbnailFilesystem->temporaryUrl($media->getPhoto(), $date);
}
else if ($filter === MediaFilterEnum::USER_MEDIUM->value) {
$path = $this->userMediumFilesystem->temporaryUrl($media->getPhoto(), $date);
}
if (isset($path)) {
$event->setUrl($path);
}
}
}
public static function getSubscribedEvents(): array
{
return [
'liip_imagine.post_resolve' => 'onPostResolve'
];
}
}