web-dev-qa-db-ja.com

Amazon SNSからのサブスクリプションリクエストHTTPを確認する方法

私はウェブ全体を検索してきましたが、Amazon SNSからのサブスクリプション要求を確認する明確な答えはありません。サブスクリプションをAmazonコンソールから自分のウェブサイトにすでに送信していますが、次は何ですか? PHPを使用するサーバーとしてAmazon EC2を使用しています。

22

AWS管理コンソールでHTTP/HTTPSエンドポイントサブスクリプションを構成する前に、PHP WebサイトのHTTPまたはHTTPSエンドポイントにHTTPを処理する機能があることを確認する必要がありますPOST Amazon SNSが生成するリクエスト。SNSメッセージにはいくつかのタイプがあります:SubscriptionConfirmation、NotificationおよびUnsubscribeConfirmation。あなたのPHPコードは、リクエストからヘッダーx-amz-sns-message-typeを取得し、メッセージタイプに基づいて処理する必要があります。 SubscriptionConfirmationメッセージの場合、PHPアプリケーションは、JSONドキュメントであるPOSTメッセージ本文を処理する必要があります。トピックをサブスクライブするには、PHPコードは、JSON本文で指定された "SubscriberURL"にアクセスする必要があります。オプションで、トピックをサブスクライブする前に、署名を検証してメッセージの信頼性を確認する必要があります。

AWSのドキュメントで詳細を確認できます: http://docs.aws.Amazon.com/sns/latest/dg/SendMessageToHttp.html

18
Lan

以下は、SNSサブスクリプションを確認する高速アプリケーション(Node.js)です。

const express = require('express')
const request = require('request')
// parse urlencoded request bodies into req.body
const bodyParser = require('body-parser')
const app = express()
const port = 8080

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.post('/', (req, res) => {
  let body = ''

  req.on('data', (chunk) => {
    body += chunk.toString()
  })

  req.on('end', () => {
    let payload = JSON.parse(body)

    if (payload.Type === 'SubscriptionConfirmation') {
      const promise = new Promise((resolve, reject) => {
        const url = payload.SubscribeURL

        request(url, (error, response) => {
          if (!error && response.statusCode == 200) {
            console.log('Yess! We have accepted the confirmation from AWS')
            return resolve()
          } else {
            return reject()
          }
        })
      })

      promise.then(() => {
        res.end("ok")
      })
    }
  })
})

app.listen(port, () => console.log('Example app listening on port ' + port + '!'))

これを使用するには、必要なパッケージをインストールする必要があります。

yarn add express request body-parser

サブスクリプションを確認すると、AWSは次の内容のPOSTリクエストをサーバーに送信します。

{
  "Type": "SubscriptionConfirmation",
  "MessageId": "XXXXXXXX-1ee3-4de3-9c69-XXXXXXXXXXXX",
  "Token": "SECRET_TOKEN",
  "TopicArn": "arn:aws:sns:us-west-2:XXXXXXXXXXXX:ses-test",
  "Message": "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:XXXXXXXXXXXX:ses-test. To confirm the subscription, visit the SubscribeURL included in this message.",
  "SubscribeURL": "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:XXXXXXXXXXXX:ses-test&Token=SECRET_TOKEN",
  "Timestamp": "2018-11-21T19:48:08.170Z",
  "SignatureVersion": "1",
  "Signature": "SECRET",
  "SigningCertURL": "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.pem"
}

ペイロードには、サーバーから要求されたSubscribeURLが含まれています。

8
czerasz

アノテーション付きのSpringクラウドSNSサブスクリプション

春のクラウドAWSはサブスクライバーの自動確認をサポートしています。このアノテーション "@NotificationSubscriptionMapping"を付けるだけです。

@Controller
@RequestMapping("/topicName")
public class NotificationTestController {

    @NotificationSubscriptionMapping
    public void handleSubscriptionMessage(NotificationStatus status) throws IOException {
        //We subscribe to start receive the message
        status.confirmSubscription();
    }

    @NotificationMessageMapping
    public void handleNotificationMessage(@NotificationSubject String subject, @NotificationMessage String message) {
        // ...
    }

    @NotificationUnsubscribeConfirmationMapping
    public void handleUnsubscribeMessage(NotificationStatus status) {
        //e.g. the client has been unsubscribed and we want to "re-subscribe"
        status.confirmSubscription();
    }
}

http://cloud.spring.io/spring-cloud-aws/spring-cloud-aws.html#_sns_support

2
Rams

指定したエンドポイントはAWS SNSエンドポイント検証サービスからデータを取得します。同じエンドポイントを使用してエンドポイントを検証し、awsから通知を取得します。

AWS SNSから送信された入力を1つのテキストファイルにダンプするだけです。

$json_write_to_text = json_decode(file_get_contents("php://input"));

AWS SNSから送信されたすべてのデータが見つかりますが、SubscriptionUrl(有効なトークンを持つエンドポイントに固有)を見つけるだけです。これをブラウザーで開くと、SubscriptionConfirmationステータスが表示されます。それでおしまい

楽しい。

2
Chintan7027

NodeJSバックエンドを使用してこれを解決しました。 HapiJSにこのようなAPIがあるとします(別の技術を使用できるかどうかは問題ではありません)

{
    method: 'POST',
    path: '/hello',
    handler: ( request, reply ) => {

        reply( Hello.print(request.payload) );
    },
    config: {
        tags: ['api']
    }
}

受け取ったペイロードをビジネスロジックに渡すだけです。

ビジネスロジックプロセスでは、次のようになります。

    'use strict';
    const request = require('request');

    exports.print = (payload) => {

    payload = JSON.parse(payload);
    if(payload.Type === 'SubscriptionConfirmation'){

        return new Promise((resolve, reject) => {
            const url = payload.SubscribeURL;
            request(url, (error, response) => {

                if (!error && response.statusCode == 200) {
                    console.log('Yess! We have accepted the confirmation from AWS');
                    return resolve();
                }
                else 
                    return reject();
            });
        });
    }

NPMのリクエストモジュールを使用して、そのようなリクエストを自動的に受け入れます。

もう1つの方法は、payloadの内容を印刷してから、payload.SubscribeURLで指定されたURLをクリックすることです。

AWSがそれを受け入れたら、サブスクリプションページでSubscription ARNPending Confirmationからトピック名を持つ複雑なname-cum-SHAに変更される確認を確認します。

1
rahuljain1311