Как я могу подтвердить HTTP-запрос на подписку от Amazon SNS

Я искал по всему Интернету и ничего не дал однозначного ответа, чтобы подтвердить запрос на подписку от Amazon SNS. Я уже отправил подписку с консоли Amazon на свой веб-сайт, но что дальше? Я использую amazon EC2 в качестве своего сервера с PHP.


person Fernando Santiago    schedule 01.04.2014    source источник
comment
Это может быть полезно: github.com/npflood/AWS-SNS-HTTP-PHP -ENDPOINT   -  person shasi kanth    schedule 13.09.2016


Ответы (5)


Прежде чем вы даже настроите подписку на конечную точку HTTP / HTTPS через консоль управления AWS, вам необходимо убедиться, что конечная точка HTTP или HTTPS вашего веб-сайта PHP имеет возможность обрабатывать запросы HTTP POST, генерируемые Amazon SNS. Существует несколько типов сообщений SNS: Подтверждение подписки, Уведомление и Подтверждение отмены подписки. Ваш PHP-код должен получить заголовок x-amz-sns-message-type из запроса и обработать его в зависимости от типа сообщения. Для сообщения SubscriptionConfirmation ваше приложение PHP должно обработать тело сообщения POST, которое является документом JSON. Чтобы подписаться на тему, ваш PHP-код должен посетить «SubscriberURL», указанный в теле JSON. При желании вы должны проверить подпись, чтобы убедиться в подлинности сообщения перед подпиской на тему.

Более подробную информацию можно найти в документации AWS: http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.html

person Lan    schedule 01.04.2014
comment
Кто-нибудь делал то же самое с помощью Python? Я не могу найти нигде в сети ни одного примера ... Мне нужно подписать конечную точку шлюза API (для разных учетных записей и регионов) на тему SNS, чтобы я мог запускать лямбда-функцию. - person Kostas Demiris; 19.01.2017
comment
Для всех, кто не может получить SubscribeURL, пожалуйста, следуйте этому. stackoverflow.com/a/51529066/4398385 - person Philip Enc; 01.06.2021

Вот экспресс-приложение (Node.js), подтверждающее подписку на SNS:

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, который запрашивается сервером.

person czerasz    schedule 21.11.2018
comment
Пришлось проголосовать за массовое убийство, извините. Рассмотрите ВСЕ, что входит в это, зависимости и т. Д., Просто для сбора данных запроса. - person Paul Allsopp; 10.11.2019
comment
Мог бы только что опубликовать бит из раздела "Как только вы подтвердите ..." и будет лучшим ответом. OP сказал, что я использую amazon EC2 в качестве своего сервера с PHP., Поэтому ответ nodejs, с которым я согласен, является излишним и бесполезным в этом контексте. - person Dawesi; 17.04.2020
comment
@CrazyMerlin, это не должно быть реализовано как есть. - person Teliov; 27.06.2020
comment
@Teliov OP конкретно говорит, что он использует PHP, и ему было представлено решение на Node. Если OP не понимает Node, как они должны это использовать? - person Paul Allsopp; 29.06.2020
comment
Я просто должен сказать в ответ на отрицательные комментарии: многие люди используют Node, и этот ответ отвечает на вопрос этой аудитории. Этот ответ меня спас - дал бы ему два голоса, если бы мог. - person darksinge; 01.08.2020

Указанная вами конечная точка будет получать данные от службы проверки конечных точек AWS SNS. Эта же конечная точка будет использоваться для проверки конечной точки и получения уведомлений от aws,

Просто скопируйте ввод, отправленный AWS SNS, в один текстовый файл, например,

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

Вы найдете все данные, отправленные AWS SNS, но просто найдите SubscriptionUrl (который будет характерен для конечной точки с действующим токеном). Откройте это в браузере, у вас будет статус SubscriptionConfirmation. Вот и все

Наслаждаться.

person Chintan7027    schedule 11.12.2017

Подписка Spring Cloud SNS с аннотацией

Spring Cloud 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

person Rams    schedule 01.12.2017
comment
Хотя эта ссылка может дать ответ на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если ссылка на страницу изменится. - Из отзыва - person Rob Quincey; 01.12.2017
comment
@RobQuincey Привет, спасибо за предложение, я обновлю свой ответ - person Rams; 01.12.2017

Я решил это с помощью бэкэнда NodeJS. Допустим, у вас есть такой API в HapiJS (ну, не имеет значения, что у вас может быть другая технология)

{
    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, чтобы автоматически принимать такие запросы.

Другой способ - распечатать содержимое payload и затем щелкнуть URL-адрес, указанный в payload.SubscribeURL.

Как только AWS принимает его, вы проверяете подтверждение на странице подписок, где Subscription ARN будет изменено с Pending Confirmation на сложное имя-кум-SHA, имеющее имя вашей темы.

person rahuljain1311    schedule 28.01.2018
comment
OP говорит, что я использую amazon EC2 в качестве своего сервера с PHP .... зачем отвечать с помощью nodejs? - person Dawesi; 17.04.2020
comment
Согласен. Но многие пользователи сталкиваются с одним и тем же Вопросом, как и я. Цель - помочь этим пользователям. - person rahuljain1311; 17.04.2020