flownative/aws-s3

此Flow包允许您将资源(资源)存储在Amazon的S3中

安装次数: 140 378

依赖项: 0

建议者: 0

安全: 0

星级: 18

关注者: 7

分支: 33

开放性问题: 9

类型:neos-package

v2.6.2 2023-04-03 09:27 UTC

README

MIT license Packagist Maintenance level: Friendhsip

Neos和Flow的AWS S3适配器

Flow包允许您将资源(资源)存储在Amazon的S3或S3兼容的存储中,并将资源发布到S3或Cloudfront。由于Neos CMS在底层使用Flow的资源管理,此适配器也适用于Neos中的所有类型的资源。

主要功能

  • 在私有S3桶中存储所有资产或仅存储特定集合
  • 将资产发布到私有或公共S3桶
  • 命令行界面用于基本任务,如连接检查或清空S3桶

使用此连接器,您可以运行一个不将任何资产(图像、PDF等)存储在本地Web服务器上的Neos网站。

安装

Flownative AWS S3连接器通过Composer作为常规Flow包安装。对于您现有的项目,只需将flownative/aws-s3包含在您的Flow或Neos分发的依赖关系中即可。

    $ composer require flownative/aws-s3:2.*

配置

为了与AWS网络服务通信,您需要提供有权访问S3的账户凭据(有关在AWS IAM中设置用户的说明,请参阅下一节)。将以下配置添加到您想要的Flow上下文中的Settings.yaml(例如,在Configuration/Production/Settings.yaml中)并确保用您自己的数据替换密钥、秘密和区域。

Flownative:
  Aws:
    S3:
      profiles:
        default:
          credentials:
            key: 'CD2ADVB134LQ9SFICAJB'
            secret: 'ak1KJAnotasecret9JamNkwYY188872MyljWJ'
          region: 'eu-central-1'

目前,您只能定义一个连接配置文件,即“默认”配置文件。未来版本可能支持额外的配置文件。

为您的数据设置桶

您可以为存储和目标分别创建单独的桶,或者使用同一个桶作为存储和目标。

桶的命名由您决定,这些名称将在稍后的配置中使用。

一个桶

在一桶设置中,相同的桶将用作存储和目标。所有资源都是公开可访问的,因此Flow可以在上传资源后立即渲染指向该资源的URL。

注意:如果您想直接从桶提供服务,则该桶必须不阻止其内容的公开访问。

此设置速度快且节省存储空间,因为资源不需要复制,只存储一次。缺点是URL有点难看,因为它们只由域名、路径和资源的SHA1组成。

https://s3.eu-central-1.amazonaws.com/storage.neos.example.com/sites/wwwexamplecom/00889c4636cd77876e154796d469955e567ce23c

要使用有意义的文件名,您需要安装带有路径重写规则的反向代理,以模拟这些文件名,或者使用CDN(例如CloudFront)。

两个桶

在两个桶的设置中,资源将被复制:原始文件存储在“存储”桶中,然后复制到“目标”桶中。每次创建或导入新资源时,它将存储在存储桶中,然后自动发布(即复制)到目标桶。

注意:如果您想直接从桶提供服务,则目标桶必须不阻止其内容的公开访问。

您可以选择这种配置,以便为您的资源提供便于人类和SEO友好的URL,因为复制到目标存储桶的对象可以有一个更具描述性的名称,其中包含资源的原始文件名(有关 publicPersistentResourceUris 选项的详细信息,请参见下文)。

测试您的设置

您可以通过执行 connect 命令来测试您的设置。如果您限制了存储桶特定子路径的访问权限,则必须指定存储桶和键前缀

    $ ./flow s3:connect --bucket test.storage.net --prefix sites/s3-test/
    Access list of objects in bucket "test.storage.neos" with key prefix "sites/s3-test/" ...
    Writing test object into bucket (arn:aws:s3:::test.storage.neos/sites/s3-test/Flownative.Aws.S3.ConnectionTest.txt) ...
    Deleting test object from bucket ...
    OK

请注意,如果您指定了带有前导斜杠 "/" 或不带斜杠的前缀,这确实会有所不同,因为相应的策略必须正确匹配模式,正如您后面可以看到的。

IAM 设置

最佳实践是创建一个用户,通过 AWS 的身份和访问管理(IAM)进行创建,该用户专门用于您的 Flow 或 Neos 实例与 S3 通信。此用户需要最少的访问权限,可以通过内联策略或通过成为具有相应策略的组的成员来定义。

以下内联策略为用户提供执行 Neos 资产管理所需的所有必要操作的权限。它设计用于与多个网站/用户共享一个存储桶,并且仅在您的存储桶的特定子路径中授予访问权限。通过使用 策略变量 将用户名作为路径段,此策略可以在多个用户之间重用(例如,通过在 IAM 组中提供它)。

有关策略中使用的权限的更多详细信息,Amazon 提供了有关 S3 如何授权桶操作的请求 的详细信息。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::test.storage.neos",
                "arn:aws:s3:::test.target.neos"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "",
                        "sites/",
                        "sites/${aws:username}/"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectExtended",
                "s3:GetObjectTorrent",
                "s3:PutObject",
                "s3:PutObjectInline",
                "s3:DeleteObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:GetObjectAcl",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::test.storage.neos/*",
                "arn:aws:s3:::test.target.neos/*"
            ]
        }
    ]
}

将资产发布到 S3 / Cloudfront

一旦配置了连接器包,您可以添加一个新发布目标,该目标使用该连接器,并将此目标分配给您的集合。

  Neos:
    Flow:
      resource:
        collections:
          persistent:
            target: 'cloudFrontPersistentResourcesTarget'
        targets:
          cloudFrontPersistentResourcesTarget:
            target: 'Flownative\Aws\S3\S3Target'
            targetOptions:
              bucket: 'target.neos.example.com'
              keyPrefix: '/'
              baseUri: 'https://abc123def456.cloudfront.net/'

由于新发布目标最初将是空的,因此您需要通过使用 resource:publish 命令将您的资产发布到新目标。

    path$ ./flow resource:publish

此命令将上传您的文件到目标,并从现在起使用计算出的远程URL来访问所有您的资产。

自定义公共URL

S3 目标支持一种自定义用户看到URL的方式。尽管存储桶中对象使用的路径和文件名相当固定(有关 baseUrikeyPrefix 选项,请参见上文),但您可能希望使用反向代理或内容分发网络来提供存储在目标存储桶中的资源。在这种情况下,您可以告诉目标根据您自己的规则生成URL。然后,您负责确保这些URL确实有效。

行为取决于使用的设置

  • 没有模式和未设置 baseUri:S3 客户端为资源返回的 URL
  • 未设置模式:baseUri,后跟资源的相对发布路径(如果有)或 SHA1,后跟文件名

假设我们已经设置了一个充当反向代理的 Web 服务器。对 assets.flownative.com 的请求被重写,使用类似于 https://assets.flownative.com/a817…cb1/logo.svg 的 URI 实际上会提供存储在存储桶中的文件,使用给定的 SHA1。

您可以通过定义包含占位符的模式来告诉目标生成这样的 URI

      targets:
        s3PersistentResourcesTarget:
          target: 'Flownative\Aws\S3\S3Target'
          targetOptions:
            bucket: 'flownativecom.flownative.cloud'
            baseUri: 'https://assets.flownative.com/'
            persistentResourceUris:
              pattern: '{baseUri}{sha1}/{filename}'

可能的占位符有

  • {baseUri} 在目标选项中定义的基本 URI
  • {bucketName} 目标存储桶的名称
  • {keyPrefix} 目标配置的键前缀
  • {sha1} 资源的 SHA1
  • {filename} 资源的全文件名,例如 "logo.svg"
  • {fileExtension} 资源的文件扩展名,例如 "svg"

切换集合的存储

如果您想从默认的本地文件系统存储迁移到远程存储,您需要将所有现有的持久化资源复制到新存储,并之后默认使用该存储。

您首先需要通过S3连接器向配置中添加一个新存储。由于您可能还想通过远程存储系统提供您的资产,因此还需要添加一个包含已发布资源的目标。

  Neos:
    Flow:
      resource:
        storages:
          s3PersistentResourcesStorage:
            storage: 'Flownative\Aws\S3\S3Storage'
            storageOptions:
              bucket: 'storage.neos.example.com'
              keyPrefix: 'sites/wwwexamplecom/'
        targets:
          s3PersistentResourcesTarget:
            target: 'Flownative\Aws\S3\S3Target'
            targetOptions:
              bucket: 'target.neos.example.com'
              keyPrefix: 'sites/wwwexamplecom/'
              baseUri: 'https://abc123def456.cloudfront.net/'

有关配置的一些注意事项

keyPrefix选项允许您在多个网站或应用程序之间共享一个存储桶。所有S3对象的键都将以前面的字符串为前缀。

baseUri选项定义了指向您已发布资源的公开可访问地址的根。在上面的示例中,baseUri指向一个需要单独设置的Cloudfront子域。直接使用S3对象的公共URI(例如,“https://s3.eu-central-1.amazonaws.com/target.neos.example.com/sites/wwwexamplecom/00889c4636cd77876e154796d469955e567ce23c/NeosCMS-2507x3347.jpg”)通常不是一个好主意,因为S3通常速度太慢,不能用作网站上常用资产的服务器。它适合下载,但不适合CSS文件或照片。

为了将资源复制到新存储,我们需要一个临时集合,它使用存储和新发布目标。

  Neos:
    Flow:
      resource:
        collections:
          tmpNewCollection:
            storage: 's3PersistentResourcesStorage'
            target: 's3PersistentResourcesTarget'

现在您可以使用resource:copy命令

    $ ./flow resource:copy --publish persistent tmpNewCollection

这将把所有文件从当前存储(本地文件系统)复制到新的远程存储。--publish标志表示此命令还发布了所有资源到新目标,您在当前存储和发布目标上的状态与在新目标上相同。

现在您可以覆盖旧的集合配置并删除临时配置

  Neos:
    Flow:
      resource:
        collections:
          persistent:
            storage: 's3PersistentResourcesStorage'
            target: 's3PersistentResourcesTarget'

清除缓存,完成。

    $ ./flow flow:cache:flush

防止在目标中取消发布资源

在某些情况下(例如,有两个堆栈的CMS设置),需要暂时防止取消发布图像或其他资源。

因此,可以将S3目标选项unpublishResources设置为false,以防止从S3目标中删除数据

Neos:
  Flow:
    resource:
      targets:
        s3PersistentResourcesTarget:
          target: 'Flownative\Aws\S3\S3Target'
          targetOptions:
            unpublishResources: false
            # ... other options here ...

禁用公共读取ACL

目标的ACL默认为“Flownative.Aws.S3.profiles.default.acl”设置,但可以通过目标选项“acl”进行覆盖。

因此,如果您想使用不同于“public-read”的ACL,例如,当使用具有冲突限制策略的CloudFront时,您可以设置上述配置设置或调整您的特定目标配置

Neos:
  Flow:
    resource:
      targets:
        s3PersistentResourcesTarget:
          target: 'Flownative\Aws\S3\S3Target'
          targetOptions:
            acl: ''

S3的完整示例配置

Neos:
  Flow:

    resource:
      storages:
        s3PersistentResourcesStorage:
          storage: 'Flownative\Aws\S3\S3Storage'
          storageOptions:
            bucket: 'storage.neos.prd.fra.flownative.net'
            keyPrefix: 'flownative/wwwneosio/'

      collections:

      # Collection which contains all persistent resources
        persistent:
          storage: 's3PersistentResourcesStorage'
          target: 's3PersistentResourcesTarget'

      targets:
        localWebDirectoryPersistentResourcesTarget:
          target: 'Neos\Flow\ResourceManagement\Target\FileSystemTarget'
          targetOptions:
            path: '%FLOW_PATH_WEB%_Resources/Persistent/'
            baseUri: '_Resources/Persistent/'
            subdivideHashPathSegment: false

        s3PersistentResourcesTarget:
          target: 'Flownative\Aws\S3\S3Target'
          targetOptions:
            bucket: 'target.neos.prd.fra.flownative.net'
            keyPrefix: 'flownative/wwwneosio/'
            baseUri: 'https://12345abcde6789.cloudfront.net/'

Flownative:
  Aws:
    S3:
      profiles:
        default:
          signature: 'v4'
          credentials:
            key: 'QD2AD2B134LQ9SF1CAJB'
            secret: 'ak1KJAnotasecret9JamNkwYY188872MyljWJ'
          region: 'eu-central-1'

路径样式端点

当使用非AWS兼容的S3存储的自定义端点时,可能需要使用此选项。

Flownative:
  Aws:
    S3:
      profiles:
        default:
          endpoint: 'https://abc.objectstorage.provider.tld/my-bucket-name'
          # Prevents the AWS client to prepend the bucket name to the hostname
          use_path_style_endpoint: true

使用Google Cloud Storage

注意:您可能可以使用Flow GCS connector代替。

Google Cloud Storage(GCS)是Google提供的一项服务,与AWS S3非常相似。实际上,GCS支持一个与S3兼容的端点,允许您使用Google的存储作为Amazon S3的替代品。但是请注意,如果您通过S3兼容服务端点访问GCS,您将无法使用Google Cloud Storage的完整功能集,并且您不能轻松地限制不同用户对特定存储桶或子路径的访问。

GCS对每个账户的存储桶数量没有限制,因此您不需要在网站或项目中共享存储桶。以下说明假设您为Neos或Flow项目使用一个专用的存储桶。

要启用S3支持,请前往您的Google Cloud Storage控制台,在设置面板中启用互操作性。一旦启用此模式,您就可以创建一个或多个访问密钥,这些密钥可以用于通过S3端点访问GCS。

Google Cloud Storage Interoperability Settings

然后您可以在S3连接器的设置中使用生成的密钥和密钥。除了常规凭证外,您还需要指定一个自定义端点,该端点指向Google的S3兼容性服务。

Flownative:
  Aws:
    S3:
      profiles:
        # Default credentials and client options
        # Override these in your settings with real values
        default:
          credentials:
            key: 'GOOGABCDEFG123456789'
            secret: 'abcdefgHIJKLMNOP1234567890QRSTUVWXYZabcd'
          endpoint: 'https://storage.googleapis.com/mybucket.flownative.net'