nipwaayoni/laravel-aws-sns

处理 AWS SNS 订阅请求和消息

v1.1.0 2021-09-02 15:47 UTC

This package is auto-updated.

Last update: 2024-09-16 06:33:44 UTC


README

此包提供了一种简单的方法,将 AWS SNS 消息处理添加到您的 Laravel 应用程序中,作为一个 REST 端点。该包可以自动确认订阅请求,并在接收到消息时派发事件。

如何创建 SNS 主题

创建 AWS SNS 主题不在此包的范围内。请参考 AWS 文档了解如何 创建主题

如何将 SNS 处理器添加到您的应用程序

使用 composer 需求此包

composer require nipwaayoni/laravel-aws-sns

注意:此包仅支持正在受支持的 Laravel 版本。目前这包括 Laravel 6 (LTS) 和 Laravel 8 或更高版本。

处理事件

请参阅 Laravel 事件文档。您需要编写一个监听器来处理与您注册的 ARNs 相关的事件。您的监听器类必须处理适当的事件,默认为 SnsMessageReceived。有关派发事件的更多选项,请参阅该部分的说明。然后您必须在 EventServiceProvider 中注册您的监听器,如事件文档中所述

use Nipwaayoni\SnsHandler\Events\SnsMessageReceived;
use App\Listeners\MySnsMessageHandler;

/**
* The event listener mappings for the application.
*
* @var array
  */
  protected $listen = [
    SnsMessageReceived::class => [
        MySnsMessageHandler::class,
    ],
  ];

在您的监听器中,handle 方法将接收一个 SnsMessageReceived 对象,可以用来访问 SnsMessage

public function handle(SnsMessageReceived $event)
{
   $message = $event->message();
   // do stuff with message
   $content = $message->content();
}

消息内容始终是一个字符串。您负责任何反序列化或其他必要的步骤来解释消息内容。

为特定 ARNs 派发特定事件

此包支持为来自特定主题的消息派发您自己的特定事件(既包括订阅事件也包括通知事件)。消息 ARNs 到事件类的映射是在您应用程序的 config/sns-handler.php 配置文件中完成的(如果项目中不存在,请确保已发布此文件)。

映射键必须是可解析的类,该类提供了一个事件 dispatch 方法(通常通过使用 Illuminate\Foundation\Events\Dispatchable 特性实现)。每个映射键的值必须是一个包含一个或多个 AWS SNS 主题 ARNs 的数组。每个 ARN 应该在映射中只出现一次。

return [
    ...
    'confirmation-events' => [
        MyApp\Events\SnsConfirmationRequestReceived::class => ['arn:aws:sns:us-west-2:123456789012:AlphaTopic'],
        Nipwaayoni\SnsHandler\Events\SnsConfirmationRequestReceived::class => ['*']
    ],
    'message-events' => [
        MyApp\Events\SnsMessageAlphaReceived::class => ['arn:aws:sns:us-west-2:123456789012:AlphaTopic'],
        MyApp\Events\SnsMessageBetaReceived::class => [
            'arn:aws:sns:us-west-2:123456789012:BetaTopic', 
            'arn:aws:sns:us-west-2:123456789012:GammaTopic'
        ],
        Nipwaayoni\SnsHandler\Events\SnsMessageReceived::class => ['*'],
    ],
];

请注意,映射是按顺序解析的,因此列表中找到的第一个匹配项将被派发。

请注意,不需要默认事件类,但如果在映射中找不到匹配的事件,则使用该 ARN 发送消息时将返回 404。

编写功能测试以测试预期的 SNS 功能

SnsHttpTestHelperTrait 有助于测试。在测试中,使用此特性使测试您的应用程序更容易。

示例测试

use Nipwaayoni\Tests\SnsHandler\SnsHttpTestHelperTrait;

public function testSnsRequestMapping(): void
{
    Bus::fake();
    $data = "Bob";
    $this->sendSnsMessage($data);
    Bus::assertDispatched(SayHelloJob::class);
}

消息签名验证

SNS 消息是经过签名的,应该在处理之前进行验证。此包将代表您执行此验证并拒绝无法验证的消息。由于消息签名验证需要消息中的加密正确属性,因此在没有实际 SNS 主题的情况下提交测试消息是一个问题。在这些情况下,您可以通过将以下内容添加到您的 .env 中来禁用此验证:

VALIDATE_SNS_MESSAGES=false

重要! 消息验证绝不应在生产应用程序中禁用。仅使用此选项来禁用测试目的的验证。

如何向我的应用程序发送 SNS 消息?

本包添加了一个路由(/api/sns/message),用于处理SNS请求。SNS消息路由响应POST请求,并期望内容与AWS的SNS消息一致。请注意,因为这是一个API路由,您在应用程序中应用的任何API中间件都将影响此路由。

您可以在此处找到订阅确认和通知消息HTTP请求的示例。

SNS消息的消息内容必须以字符串值提供。如果您的有效负载不是简单的字符串(例如,数组或其他类型的对象),您需要在发送之前使用类似json_encode()之类的工具序列化您的数据。

直接向您的应用POST

Amazon在此处提供了一个POST请求的示例。您可以在消息字段中添加序列化的消息。请注意,手动POST的消息无法进行验证(请参见上面的说明以禁用消息验证)。我们建议只在测试期间尝试此操作,绝不要在生产环境中进行。

如何在AWS中订阅您的端点

在订阅您的主题时,您将使用消息处理路由的完整URL。该路由将是{您的应用程序的基础URL}/api/sns/message按照这些说明使用HTTPS订阅您的端点

此包默认配置为自动响应对其端点发送的所有SNS订阅确认请求。您可以通过在.env文件中添加以下内容来禁用此功能:

AUTO_CONFIRM_SUBSCRIPTIONS=false

注意:只有当您的端点可以从AWS SNS服务(即公共互联网)访问时,您才能订阅您的端点。

开发

此包应与包括LTS版本在内的支持的Laravel版本一起工作。在开发过程中,您应该确保运行测试并验证不同版本下的预期行为。由于我们使用了orchestra/testbench包,您可以使用composer轻松地在安装的Laravel框架版本之间切换。

# Laravel 6
composer require --dev orchestra/testbench:^4.0 -W
# Laravel 8
composer require --dev orchestra/testbench:^6.0 -W

应将Laravel的新版本添加到.github/workflows/run-tests.yml中的GitHub工作流程矩阵中。