Skip to content

Instantly share code, notes, and snippets.

@edamov
Created October 18, 2016 15:52
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save edamov/c1f70c744cd8c28d0a6870d5b50b77d6 to your computer and use it in GitHub Desktop.
Save edamov/c1f70c744cd8c28d0a6870d5b50b77d6 to your computer and use it in GitHub Desktop.
PHP token-based (JWT) push notifications to APNS via HTTP/2
<?php
require_once 'vendor/autoload.php';
use Jose\Factory\JWKFactory;
use Jose\Factory\JWSFactory;
$key_file = 'key.p8';
$secret = null; // If the key is encrypted, the secret must be set in this variable
$private_key = JWKFactory::createFromKeyFile($key_file, $secret, [
'kid' => 'ABCDEFGH12', // The Key ID obtained from your developer account
'alg' => 'ES256', // Not mandatory but recommended
'use' => 'sig', // Not mandatory but recommended
]);
$payload = [
'iss' => 'JKLMNOPQRS',
'iat' => time(),
];
$header = [
'alg' => 'ES256',
'kid' => $private_key->get('kid'),
];
$jws = JWSFactory::createJWSToCompactJSON(
$payload,
$private_key,
$header
);
var_dump($jws);
function sendHTTP2Push($http2ch, $http2_server, $app_bundle_id, $message, $token, $jws) {
// url (endpoint)
$url = "{$http2_server}/3/device/{$token}";
// headers
$headers = array(
"apns-topic: {$app_bundle_id}",
'Authorization: bearer ' . $jws
);
// other curl options
curl_setopt_array($http2ch, array(
CURLOPT_URL => $url,
CURLOPT_PORT => 443,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $message,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HEADER => 1
));
// go...
$result = curl_exec($http2ch);
if ($result === FALSE) {
throw new Exception("Curl failed: " . curl_error($http2ch));
}
print_r($result);
// get response
$status = curl_getinfo($http2ch);
return $status;
}
// this is only needed with php prior to 5.5.24
if (!defined('CURL_HTTP_VERSION_2_0')) {
define('CURL_HTTP_VERSION_2_0', 3);
}
// open connection
$http2ch = curl_init();
curl_setopt($http2ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
// send push
$message = '{"aps":{"alert":"Hi!","sound":"default"}}';
$token = 'aaaaaaaa';
$http2_server = 'https://api.development.push.apple.com'; // or 'api.push.apple.com' if production
$app_bundle_id = 'com.app.Test';
sendHTTP2Push($http2ch, $http2_server, $app_bundle_id, $message, $token, $jws);
// close connection
curl_close($http2ch);
@vishalkalola1
Copy link

how many dependency use in require_once 'vendor/autoload.php??

@Matheus-de-Souza
Copy link

Matheus-de-Souza commented Apr 25, 2017

@vishalkalola1

I think he used only this lib JSON Object Signing and Encryption library

You can install it with Composer composer require spomky-labs/jose

This lib needs PHP 5.6

@AlexanderMatveev
Copy link

@edamov getting {"reason":"InvalidProviderToken"}

@AlexanderMatveev
Copy link

@hepspl
Copy link

hepspl commented Mar 7, 2021

Hi, do you know how to deal with

"Uncaught Exception: Curl failed: GnuTLS recv error (-110): The TLS connection was non-properly terminated"

problem?

@Talhasahi
Copy link

@edamov @vishalkalola1 @AlexanderMatveev i am receiving"reason":"BadDeviceToken" .. please help me

@vishalkalola1
Copy link

Get new device token from ios device and try again. @Talhasahi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment