J'ai cherché partout sur le Web et rien ne donne une réponse claire pour confirmer la demande d'abonnement d'Amazon SNS. J'envoie déjà l'abonnement depuis la console Amazon à mon site Web, mais quelle est la prochaine étape? J'utilise Amazon EC2 comme serveur avec PHP.
Avant même de configurer l'abonnement au point de terminaison HTTP/HTTPS via la console de gestion AWS, vous devez vous assurer que le point de terminaison HTTP ou HTTPS de votre site Web PHP a la capacité de gérer le HTTP POST requêtes générées par Amazon SNS. Il existe plusieurs types de messages SNS: SubscriptionConfirmation , Notification et UnsubscribeConfirmation. Your PHP doit obtenir l'en-tête x-amz-sns-message-type à partir de la demande et le traiter en fonction du type de message. Pour le message SubscriptionConfirmation, votre application PHP doit traiter le corps de message POST, qui est un document JSON. Pour souscrire le sujet, votre PHP doit visiter le "SubscriberURL" spécifié dans le corps JSON. Facultativement, vous devez vérifier la signature pour vous assurer de l'authenticité du message avant de vous abonner au sujet.
Vous pouvez trouver plus de détails sur la documentation AWS: http://docs.aws.Amazon.com/sns/latest/dg/SendMessageToHttp.html
Voici une application express (Node.js) qui confirme l'abonnement 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 + '!'))
Pour l'utiliser, il faut installer les packages requis:
yarn add express request body-parser
Une fois que vous avez confirmé l'abonnement, AWS enverra une demande POST
au serveur avec le contenu suivant:
{
"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"
}
La charge utile contient SubscribeURL
qui est demandée par le serveur.
Abonnement SNS Spring Cloud avec annotation
spring Cloud AWS prend en charge la confirmation automatique de l'abonné, il vous suffit de mettre cette annotation "@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
Le point de terminaison que vous avez spécifié obtiendra les données du service de vérification des points de terminaison AWS SNS. Le même point de terminaison sera utilisé pour vérifier le point de terminaison et recevoir des notifications de aws,
Vider simplement l'entrée envoyée par AWS SNS dans un fichier texte comme,
$json_write_to_text = json_decode(file_get_contents("php://input"));
Vous trouverez toutes les données envoyées par AWS SNS, mais il vous suffit de trouver SubscriptionUrl
(qui sera spécifique au point de terminaison ayant un jeton valide). Ouvrez-le dans le navigateur, vous aurez le statut SubscriptionConfirmation. C'est tout
Prendre plaisir.
J'ai résolu cela en utilisant le backend NodeJS. Disons que vous avez une API comme celle-ci dans HapiJS (Eh bien, peu importe que vous puissiez avoir une autre technologie)
{
method: 'POST',
path: '/hello',
handler: ( request, reply ) => {
reply( Hello.print(request.payload) );
},
config: {
tags: ['api']
}
}
Passez simplement la charge utile que vous recevez à votre logique métier.
Dans le processus de logique métier, il ressemble à ceci
'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();
});
});
}
J'utilise le module de demande de NPM pour accepter automatiquement ces demandes.
Une autre façon serait d'imprimer le contenu de payload
puis de cliquer sur l'URL indiquée dans payload.SubscribeURL
.
Une fois qu'AWS l'accepte, vous vérifiez la confirmation sur la page Abonnements où Subscription ARN
serait changé de Pending Confirmation
à un nom complexe-SHA ayant le nom de votre sujet.