2014-04-29 7 views
1

Je tente de créer une SharedAccessSignature pour l'API Azure Notifications Hubs en PHP.API REST Azure Notification Hubs avec PHP

Je reçois toujours l'erreur "Signature de jeton d'autorisation invalide".

Quelqu'un at-il un exemple de création de SAS dans PHP 5.4+? Il existe une documentation de l'API sur: http://msdn.microsoft.com/en-us/library/dn170477.aspx, mais certaines personnes disent que l'implémentation diffère de la documentation.

Ceci est ma mise en œuvre ne:

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; 
} 

Répondre

3

Voici une simple enveloppe pour envoyer des notifications aux hubs de notification avec 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; 
    } 
} 

?> 

Je ne sais pas si vous vouliez envoyer des poussées ou faire de la gestion des inscriptions. Il n'est pas difficile de modifier ce qui précède pour faire la gestion de l'enregistrement comme indiqué dans les API NH REST (souvenez-vous de l'ordre dans les documents xml questions!): http://msdn.microsoft.com/en-us/library/dn223264.aspx. Faites-moi savoir si vous rencontrez toujours des problèmes.

Elio

+1

Salut Elio, Avec votre code, j'ai pu se connecter avec succès à l'API de notification Hub, obtenir une réponse 201 lors de la présentation d'une notification push. Mais toutes mes notifications push ne sont pas envoyées, mais enregistrées sous la métrique "toutes les erreurs channell" dans le panneau de contrôle azure. Est-il possible d'inclure le fichier notification.php également? Peut-être que j'ai fait une erreur avec les en-têtes spécifiques ou quelque chose. – thiver

+0

Bonjour Elio, j'ai toujours des problèmes avec l'API du concentrateur de notification. Obtenir une réponse 201 n'est pas un problème, mais aucune notification n'est envoyée. L'envoi d'une notification avec le panneau DEBUG fonctionne. Donc ça doit être quelque chose avec ma charge utile de notification ou mes en-têtes. – thiver

+0

À partir d'aujourd'hui, tout semble fonctionner avec la même base de code, certains problèmes internes avec Azure Notification Hubs? Pousser pour iOS et Windows Phone le fait bien maintenant. – thiver