私はウェブ全体を検索してきましたが、Amazon SNSからのサブスクリプション要求を確認する明確な答えはありません。サブスクリプションをAmazonコンソールから自分のウェブサイトにすでに送信していますが、次は何ですか? PHPを使用するサーバーとしてAmazon EC2を使用しています。
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
以下は、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
が含まれています。
アノテーション付きの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
指定したエンドポイントはAWS SNSエンドポイント検証サービスからデータを取得します。同じエンドポイントを使用してエンドポイントを検証し、awsから通知を取得します。
AWS SNSから送信された入力を1つのテキストファイルにダンプするだけです。
$json_write_to_text = json_decode(file_get_contents("php://input"));
AWS SNSから送信されたすべてのデータが見つかりますが、SubscriptionUrl
(有効なトークンを持つエンドポイントに固有)を見つけるだけです。これをブラウザーで開くと、SubscriptionConfirmationステータスが表示されます。それでおしまい
楽しい。
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 ARN
がPending Confirmation
からトピック名を持つ複雑なname-cum-SHAに変更される確認を確認します。