web-dev-qa-db-fra.com

Nouvelle API de fournisseur APNS et PHP

J'ai commencé à créer du code basé sur this pour l'envoi de notifications Push à partir de PHP.

Cependant, maintenant que j'ai compris qu'il existe une nouvelle API qui utilise HTTP/2 et fournit un retour dans la réponse, j'essaie de comprendre ce que je dois faire pour obtenir ce retour.

Je n'ai pas été capable de trouver des tutoriels ou des exemples de code pour me guider (je suppose parce que c'est tellement nouveau).

Est-il possible d'utiliser la méthode stream_socket_client() pour se connecter à APNS avec la nouvelle API de fournisseur? Comment puis-je obtenir les commentaires? Tout ce que je reçois de fwrite($fp, $msg, strlen($msg)) maintenant, c’est un numéro. À toutes fins utiles, vous pouvez considérer mon code comme identique à celui de la question SO sur laquelle j'ai basé mon code

Merci!

17
Ben Holness

Avec la nouvelle API de fournisseur HTTP/2 APNS, vous pouvez utiliser curl pour envoyer des notifications Push.

MODIFIER

Avant de continuer (comme noté par @Madox), openssl> = 1.0.2e of doit être installé (à partir du paquet de préférence). Vérifier avec la commande 

openssl version

a) Votre version de PHP doit être> = 5.5.24 pour que la constante CURL_HTTP_VERSION_2_0 soit définie.

b) Assurez-vous que la version 7.46+ de Curl est installée sur votre système avec 

curl --version

c) Curl devrait avoir le support http/2 activé. Dans la sortie lorsque vous tapez la commande précédente, vous devriez voir une ligne comme celle-ci:

Features: IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets 

si HTTP2 ne s'affiche pas, vous pouvez suivre cet excellent tutoriel pour installer http/2 for curl https://serversforhackers.com/video/curl-with-http2-support

Vérifiez que curl détecte openssl> = 1.0.2e, en effectuant curl --version, vous obtiendrez quelque chose comme ceci:

curl 7.47.1 (x86_64-pc-linux-gnu) libcurl/7.47.1 OpenSSL/1.0.2f zlib/1.2.8 libidn/1.28 nghttp2/1.8.0-DEV librtmp/2.3

e) Une fois que vous avez tout installé, vous pouvez le tester en ligne de commande:

curl -d '{"aps":{"alert":"hi","sound":"default"}}' \ 
--cert <your-certificate.pem>:<certificate-password> \ 
-H "apns-topic: <your-app-bundle-id>" \ 
--http2  \ 
https://api.development.Push.Apple.com/3/device/<device-token>

f) Voici un exemple de code dans PHP que j'ai essayé avec succès:

if(defined('CURL_HTTP_VERSION_2_0')){

    $device_token   = '...';
    $pem_file       = 'path to your pem file';
    $pem_secret     = 'your pem secret';
    $apns_topic     = 'your apns topic. Can be your app bundle ID';


    $sample_alert = '{"aps":{"alert":"hi","sound":"default"}}';
    $url = "https://api.development.Push.Apple.com/3/device/$device_token";

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $sample_alert);
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("apns-topic: $apns_topic"));
    curl_setopt($ch, CURLOPT_SSLCERT, $pem_file);
    curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $pem_secret);
    $response = curl_exec($ch);
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    //On successful response you should get true in the response and a status code of 200
    //A list of responses and status codes is available at 
    //https://developer.Apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html#//Apple_ref/doc/uid/TP40008194-CH107-SW1

    var_dump($response);
    var_dump($httpcode);

}
31
tiempor3al

J'utilise CentOS 6 et la solution consistait à installer à partir des sources cURL et OpenSSL.

Cela peut sembler très simple, mais il m'a fallu 3 jours pour trouver la bonne configuration pour les paquets et je pense pouvoir aider quelqu'un en publiant ce que j'ai fait ici.

Cela s'est avéré un peu délicat pour moi car je ne suis pas habitué à installer des packages à partir des sources, mais je peux maintenant me connecter aux APN via HTTPS via HTTP/2.

Les détails de ce que j'ai fait sont ici:

  1. Téléchargez et décompressez cURL et OpenSSL:

    wget https://curl.haxx.se/download/curl-7.47.1.tar.gz
    wget https://www.openssl.org/source/openssl-1.0.2h.tar.gz
    
  2. Configurez OpenSSL avec les drapeaux suivants (je ne sais pas ce qu’ils font, mais c’est ce qui a fonctionné pour moi):

    export CXXFLAGS="$CXXFLAGS -fPIC"
    ./config zlib enable-ssl3 enable-shared
    
  3. faire et installer OpenSSL

  4. Configurez cURL avec l'indicateur suivant:

    ./configure --with-ssl=/usr/local/ssl/
    
  5. Faire et installer cURL

  6. définir LD_LIBRARY_PATH sur/usr/local/ssl/lib /

    export LD_LIBRARY_PATH=/usr/local/ssl/lib/                  
    
  7. Tester

    /usr/local/bin/curl -v -d '{"aps":{"alert":"hi","sound":"default"}}' --cert cert.crt --key cert.key -H "apns-topic: topics" --http2 https://api.development.Push.Apple.com:443/3/device/00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0
    

Le résultat:

*   Trying 17.172.238.203...
* Connected to api.development.Push.Apple.com (17.172.238.203) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=api.development.Push.Apple.com; OU=management:idms.group.533599; O=Apple Inc.; ST=California; C=US
*  start date: Jun 19 01:49:43 2015 GMT
*  expire date: Jul 18 01:49:43 2017 GMT
*  subjectAltName: Host "api.development.Push.Apple.com" matched cert's "api.development.Push.Apple.com"
*  issuer: CN=Apple IST CA 2 - G1; OU=Certification Authority; O=Apple Inc.; C=US
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* TCP_NODELAY set
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x1091110)
> POST /3/device/00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0 HTTP/1.1
> Host: api.development.Push.Apple.com
> User-Agent: curl/7.48.0
> Accept: */*
> apns-topic: topics
> Content-Length: 40
> Content-Type: application/x-www-form-urlencoded
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
* We are completely uploaded and fine
< HTTP/2.0 400
<
* Connection #0 to Host api.development.Push.Apple.com left intact
{"reason":"BadDeviceToken"}

Comme vous pouvez le voir, je me suis débarrassé du moche

▒@@▒HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 504f5354202f332f6465766963652f746573742048545450
4
Samo

Je pouvais envoyer avec succès Push via HTTP2 en utilisant php CURL et lire les commentaires directement dans le corps de la réponse (ici, j'ai écrit un court tutoriel sur la procédure à suivre: Envoi d'une notification push avec HTTP2 (et PHP) ) . Je pense que vous pouvez vérifier la lecture du corps de la réponse depuis le socket (je ne me souviens pas exactement de la fonction php, peut-être "fgets").

4
valfer

Pour résoudre les erreurs HTTP/2 client preface string missing or corrupt dans PHP 5.6, j'ai créé une image Docker Apache et CLI PHP sur laquelle vous pouvez vous appuyer ou tout simplement rechercher Dockerfile pour construire le vôtre. Même chose peut probablement s'appliquer à PHP 7.0 bien que je n'ai pas essayé.

1
Norbert

Suivez ce guide [ http://cloudfields.net/blog/ios-Push-notifications-encryption/][1] pour générer et fusionner votre certificat et votre clé privée. pkey comme décrit dans le guide avec les mêmes noms de fichier, essayez simplement la commande curl ci-dessous.

curl -X POST -H 'apns-topic: com.mycompany.ios.BadassApp' -d '{"aps":{"content-available":1,"alert":"hi","sound":"default"}}' --cert apns_cert.pem:yourCertPassword --http2 'https://api.development.Push.Apple.com:443/3/device/b8de1sf067effefc398d792205146fc67dn0e96b0ff21ds81cabe384bbe71353'
1
KeranMarinov