Nueva API de proveedor APNS y PHP
ios iphone (7)
Con la nueva API del proveedor de APNS HTTP / 2, puede usar el enrollamiento para enviar notificaciones de inserción.
EDITAR
Antes de continuar (como lo indica @Madox), se debe instalar openssl> = 1.0.2e of (preferiblemente del paquete). Verificar con el comando
openssl version
a) Su versión de PHP debería ser> = 5.5.24 para que se defina la constante CURL_HTTP_VERSION_2_0.
b) Asegúrese de tener instalada la versión 7.46+ de curl en su sistema con
curl --version
c) Curl debería tener habilitado el soporte http / 2. En la salida al escribir el comando anterior, debería ver una línea como esta:
Features: IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets
Si no aparece HTTP2, puede seguir este excelente tutorial para instalar http / 2 para curl https://serversforhackers.com/video/curl-with-http2-support
Verifique que el enrollamiento detectado openssl> = 1.0.2e, hacer curl --version debería generar algo como esto:
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) Una vez que haya instalado todo, puede probarlo en la línea de comando:
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) Aquí hay un código de ejemplo en PHP que he probado exitosamente:
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);
}
Comencé a crear un código basado en this para enviar notificaciones push desde PHP.
Sin embargo, ahora que entendí que hay una nueva API que utiliza HTTP / 2 y proporciona comentarios en la respuesta, estoy tratando de averiguar qué debo hacer para obtener esos comentarios.
No he podido encontrar ningún tutorial o código de muestra para orientarme (supongo que es muy nuevo).
¿Es posible utilizar el método stream_socket_client()
para conectarse a APNS con la nueva API del proveedor? ¿Cómo obtengo los comentarios? Todo lo que recibo de fwrite($fp, $msg, strlen($msg))
ahora es un número. Para todos los efectos, puede considerar mi código igual que el código de this
¡Gracias!
Estoy usando CentOS 6 y la forma de resolverlo fue instalar desde la fuente cURL y OpenSSL.
Puede parecer muy simple, pero me tomó 3 días encontrar la configuración correcta para los paquetes, así que creo que puedo ayudar a alguien publicando lo que hice aquí.
Me resultó un poco difícil ya que no estoy acostumbrado a instalar paquetes desde la fuente, pero ahora puedo conectarme a los APN utilizando HTTPS sobre HTTP / 2.
Los detalles de lo que hice están aquí:
Descarga y descomprime cURL y 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
Configure OpenSSL con los siguientes indicadores (no estoy seguro de lo que hacen, pero es lo que funcionó para mí):
export CXXFLAGS="$CXXFLAGS -fPIC" ./config zlib enable-ssl3 enable-shared
hacer e instalar OpenSSL
Configure cURL con la siguiente bandera:
./configure --with-ssl=/usr/local/ssl/
Hacer e instalar cURL
establezca LD_LIBRARY_PATH en / usr / local / ssl / lib /
export LD_LIBRARY_PATH=/usr/local/ssl/lib/
Prueba
/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
El resultado:
* 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"}
Como puedes ver, me deshice de lo feo
▒@@▒HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 504f5354202f332f6465766963652f746573742048545450
Para resolver errores HTTP/2 client preface string missing or corrupt
en PHP 5.6 Creé una imagen de Apache y CLI PHP Docker en la que podría confiar o simplemente busque lo que hice en el Dockerfile para crear la suya propia. Probablemente se puede aplicar lo mismo a PHP 7.0 aunque no lo he intentado.
Podía enviar con éxito push a través de HTTP2 usando php CURL y leer los comentarios directamente en el cuerpo de la respuesta (aquí escribí un breve tutorial sobre cómo hacer esto: Enviar notificaciones push con HTTP2 (y PHP) ). Creo que se puede verificar la lectura del cuerpo de respuesta desde el socket (no recuerdo exactamente la función php, tal vez "fgets").
Quiero agregar algo de información a la respuesta temporal.
1) el enrollamiento debe compilarse con la versión openssl> = 1.0.2 para que sea totalmente compatible con http / 2. Recibo el error "? @@? HTTP / 2 del prólogo del cliente que falta o está dañado ..." cuando lo compilé con CentOS stock openssl-1.0.1e.
2) Si su versión del módulo php mod_curl.so compiló sin la constante CURL_HTTP_VERSION_2_0, podría reemplazarla con el número entero 3:
curl_setopt($ch, CURLOPT_HTTP_VERSION, 3);
Siga esta guía [ http://cloudfields.net/blog/ios-push-notifications-encryption/][1] para generar y fusionar su certificado y clave privada. Una vez que haya fusionado y su sslcert y pkey como se describe en la guía con los mismos nombres de archivo, simplemente intente el comando curl a continuación.
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''
si es posible:
$errno=0;$errstr="";
$sock = stream_socket_client(
"api.push.apple.com:443",
$errno,
$errstr,
4,
STREAM_CLIENT_CONNECT,
stream_context_create(["ssl" => ["local_cert" => "/path/to/cert.pem","verify_peer"=>false,"verify_peer_name"=>false]])
);
stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);