2012-08-27 33 views
4

如何通過http確認訂閱亞馬遜SNS?我目前正在爲我的應用程序使用Rails,並希望收到我的電子郵件反彈通知。所以,我試圖通過亞馬遜論壇尋找,最近我發現是:https://forums.aws.amazon.com/thread.jspa?threadID=87555它告訴我使用request.raw_post來獲取請求和JSON解析它。但是,當我嘗試這樣做時,它給了我一個錯誤,說請求是空的。我是否正確地做這件事?有人可以指導我如何從Amazon SNS獲取訂閱令牌,以便我可以確認我的訂閱嗎?謝謝! :)如何從Amazon SNS訂閱獲取HTTP中的令牌?

+1

是的,解析請求主體應該產生一個散列,其中包含確認令牌。如果你發佈了一些代碼,回答這個問題會更容易。 – benzado

回答

0

這是一個PHP scrit,適合我。 (有一些日誌行把它寫到文件i /tmp/log.txt中,它有助於調試正在發生的事情。首先,我從https://sns.us-east-1.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem下載了亞馬遜證書。一定還要隨地使用utf8。

對我來說,它僅適用於HTTP協議。我看不到服務器中的任何訪問時,我訂閱的HTTPS URL。

<?php 

mLog ("\n\n----------------Start Receive -------------\n"); 

require_once APP_DIR . 'util/AWSSDKforPHP/sdk.class.php'; 

$h= fopen("php://input","r"); 
$X = stream_get_contents($h); 


$J = json_decode($X , true); 

mLog("Received body: \n" . json_encode($J). "\n"); 

function mLog($Msg) { 
    file_put_contents(sys_get_temp_dir() .'/log.txt',$Msg,FILE_APPEND); 
} 


function CheckCall($J) { 

    if ($J["Type"]=="Notification") { 
     $SB=''; 
     $SB .= "Message\n"; 
     $SB .= $J["Message"] . "\n"; 
     $SB .= "MessageId\n"; 
     $SB .= $J["MessageId"] . "\n"; 

     if ($J["Subject"] != null) { 
      $SB .= "Subject\n"; 
      $SB .= $J["Subject"]. "\n"; 
     } 

     $SB .= "Timestamp\n"; 
     $SB .= $J["Timestamp"] . "\n"; 

     $SB .="TopicArn\n"; 
     $SB .= $J["TopicArn"]."\n"; 
     $SB .="Type\n"; 
     $SB .=$J["Type"]."\n"; 

    } else if ($J["Type"]=="SubscriptionConfirmation") { 
     $SB=''; 
     $SB .= "Message\n"; 
     $SB .= $J["Message"] . "\n"; 
     $SB .= "MessageId\n"; 
     $SB .= $J["MessageId"] . "\n"; 
     $SB .= "SubscribeURL\n"; 
     $SB .= $J["SubscribeURL"] . "\n"; 
     $SB .= "Timestamp\n"; 
     $SB .= $J["Timestamp"] . "\n"; 

     $SB .= "Token\n"; 
     $SB .= $J["Token"] ."\n"; 
     $SB .="TopicArn\n"; 
     $SB .= $J["TopicArn"]."\n"; 
     $SB .="Type\n"; 
     $SB .=$J["Type"]."\n"; 
    } else { 
     $SB=''; 
    } 


    $cert = file_get_contents('SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem'); 
    $pubkey_id = openssl_get_publickey($cert); 

    mLog("Signed string:\n" . $SB . "End Signed string\n"); 

    $Sig=base64_decode($J["Signature"]); 
    if (openssl_verify($SB, $Sig, $pubkey_id)) { 
     return true; 
    } else { 

     return false; 
    } 
} 

if (!CheckCall($J)) { 
    mLog("Authorization failed. \n"); 
    header('HTTP/1.1 500 Internal Server Error'); 
    echo "<html><head></head><body>".sys_get_temp_dir()."</body></html>"; 

    exit(0); 
} 

$sns = new AmazonSNS(); 

if ($J["Type"]=="SubscriptionConfirmation") { 
    $Res = $sns->confirm_subscription($J["TopicArn"], $J["Token"]); 
    mLog("confitm_subscription sended: \n" . json_encode($Res)); 
} else if ($J["Type"]=="Notification") { 
    mLog("-----------Begin Message-----------\n"); 
    mLog("Subject: ".$J["Subject"]. "\n"); 
    mLog($J["Message"]); 
    mLog("\n-----------End Messagr------------\n\n"); 

} else { 
    mLog("Invalid type \n"); 
} 
echo "<html><head></head><body>Authentication Error</body></html>"; 
1

這爲我工作。在你的控制器,創建一個動作類似的代碼下面是你想要的令牌路由,所以你可以在那裏看到它,但是我選擇了SubscribeURL路由,並且只是在URL上做了一個GET。

def sns 
    request_json = JSON.parse(request.raw_post, {symbolize_names: true}) 
    subscribe_url = request_json[:SubscribeURL] 
    token = request_json[:Token] 
    end