【问题标题】:Azure Notification Hubs REST API with PHP带有 PHP 的 Azure 通知中心 REST API
【发布时间】:2014-04-29 09:33:10
【问题描述】:

我正在尝试在 PHP 中为 Azure Notifications Hubs API 创建一个 SharedAccessSignature。

我不断收到错误“无效的授权令牌签名”。

谁有在 PHP 5.4+ 中创建 SAS 的例子? 在:http://msdn.microsoft.com/en-us/library/dn170477.aspx 上有一些 API 的文档,但有人说实现与文档不同。

这是我失败的实现:

private static function get_authentication_header()
    {
        $uri = "https://x.servicebus.windows.net/x";
        $expiry = time() + (60*60);
        $string = utf8_encode(urlencode($uri) . "\n" . $expiry);
        $keyname = "DefaultFullSharedAccessSignature";
        $key = base64_decode(static::HUB_KEY);
        $signature = base64_encode(hash_hmac('sha256', $string,  $key));
        $sas = 'SharedAccessSignature sig=' . $signature . '&se=' . $expiry . '&skn=' .      $keyname . '&sr=' . urlencode($uri);
        return $sas;
 }

【问题讨论】:

    标签: php azure push-notification


    【解决方案1】:

    这是一个使用 PHP 向通知中心发送通知的简单包装器。

    <?php
    
    include 'Notification.php';
    
    class NotificationHub {
    
        const API_VERSION = "?api-version=2013-10";
    
        private $endpoint;
        private $hubPath;
        private $sasKeyName;
        private $sasKeyValue;
    
        function __construct($connectionString, $hubPath) {
            $this->hubPath = $hubPath;
    
            $this->parseConnectionString($connectionString);
        }
    
        private function parseConnectionString($connectionString) {
            $parts = explode(";", $connectionString);
            if (sizeof($parts) != 3) {
                throw new Exception("Error parsing connection string: " . $connectionString);
            }
    
            foreach ($parts as $part) {
                if (strpos($part, "Endpoint") === 0) {
                    $this->endpoint = "https" . substr($part, 11);
                } else if (strpos($part, "SharedAccessKeyName") === 0) {
                    $this->sasKeyName = substr($part, 20);
                } else if (strpos($part, "SharedAccessKey") === 0) {
                    $this->sasKeyValue = substr($part, 16);
                }
            }
        }
    
        private function generateSasToken($uri) {
            $targetUri = strtolower(rawurlencode(strtolower($uri)));
    
            $expires = time();
            $expiresInMins = 60;
            $expires = $expires + $expiresInMins * 60;
            $toSign = $targetUri . "\n" . $expires;
    
            $signature = rawurlencode(base64_encode(hash_hmac('sha256', $toSign, $this->sasKeyValue, TRUE)));
    
            $token = "SharedAccessSignature sr=" . $targetUri . "&sig="
                        . $signature . "&se=" . $expires . "&skn=" . $this->sasKeyName;
    
            return $token;
        }
    
        public function broadcastNotification($notification) {
            $this->sendNotification($notification, "");
        }
    
        public function sendNotification($notification, $tagsOrTagExpression) {
            echo $tagsOrTagExpression."<p>";
    
            if (is_array($tagsOrTagExpression)) {
                $tagExpression = implode(" || ", $tagsOrTagExpression);
            } else {
                $tagExpression = $tagsOrTagExpression;
            }
    
            # build uri
            $uri = $this->endpoint . $this->hubPath . "/messages" . NotificationHub::API_VERSION;
    
            echo $uri."<p>";
    
            $ch = curl_init($uri);
    
            if (in_array($notification->format, ["template", "apple", "gcm"])) {
                $contentType = "application/json";
            } else {
                $contentType = "application/xml";
            }
    
            $token = $this->generateSasToken($uri);
    
            $headers = [
                'Authorization: '.$token,
                'Content-Type: '.$contentType,
                'ServiceBusNotification-Format: '.$notification->format
            ];
    
            if ("" !== $tagExpression) {
                $headers[] = 'ServiceBusNotification-Tags: '.$tagExpression;
            }
    
            # add headers for other platforms
            if (is_array($notification->headers)) {
                $headers = array_merge($headers, $notification->headers);
            }
    
            curl_setopt_array($ch, array(
                CURLOPT_POST => TRUE,
                CURLOPT_RETURNTRANSFER => TRUE,
                CURLOPT_SSL_VERIFYPEER => FALSE,
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_POSTFIELDS => $notification->payload
            ));
    
            // Send the request
            $response = curl_exec($ch);
    
            // Check for errors
            if($response === FALSE){
                throw new Exception(curl_error($ch));
            }
    
            $info = curl_getinfo($ch);
    
            if ($info['http_code'] <> 201) {
                throw new Exception('Error sending notificaiton: '. $info['http_code'] . ' msg: ' . $response);
            }
    
            //print_r($info);
    
            //echo $response;
        } 
    }
    
    ?>
    

    我不知道您是想发送推送还是进行注册管理。如NH REST APIs所示,修改上述内容进行注册管理并不难(记住xml文档中的顺序很重要!):http://msdn.microsoft.com/en-us/library/dn223264.aspx

    如果您仍然遇到问题,请告诉我。

    埃利奥

    【讨论】:

    • 您好 Elio,使用您的代码,我能够成功连接到 Notification Hub API,在提交推送通知时收到 201 响应。但是我的所有推送通知都没有发送,而是记录在 azure 控制面板中的“所有通道错误”指标下。是否也可以包含 notification.php 文件?也许我在特定的标题或其他东西上犯了一个错误。
    • 您好 Elio,我仍然遇到通知中心 API 的问题。获得 201 响应没有问题,但不会发送任何通知。使用 DEBUG 面板发送通知是可行的。所以它一定是我的通知有效负载或标头。
    • 到目前为止,一切似乎都可以使用相同的代码库,Azure 通知中心存在一些内部问题吗? Push for iOS 和 Windows Phone 现在做得很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 2018-04-22
    • 2015-09-26
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    相关资源
    最近更新 更多