Send iOS Push notification in php with .p8 file
Asked Answered
M

3

14

Apple has updated their push notification service and the certificate file received is now a .p8 file. There are many examples online of how to send a push notification with the .pem file but I can't find anything for a .p8 file. Does anyone have any code that works with the .p8 file?

Madox answered 13/1, 2017 at 6:5 Comment(0)
F
20

With the script below I'm able to send token-based push notifications with the .p8 file.

The minimum version of curl supporting this is 7.38.0, and it must be compiled with the flag --with-nghttp2 and openssl >= 1.0.2

<?php

  $keyfile = 'AuthKey_AABBCC1234.p8';               # <- Your AuthKey file
  $keyid = 'AABBCC1234';                            # <- Your Key ID
  $teamid = 'AB12CD34EF';                           # <- Your Team ID (see Developer Portal)
  $bundleid = 'com.company.YourApp';                # <- Your Bundle ID
  $url = 'https://api.development.push.apple.com';  # <- development url, or use http://api.push.apple.com for production environment
  $token = 'e2c48ed32ef9b018........';              # <- Device Token

  $message = '{"aps":{"alert":"Hi there!","sound":"default"}}';

  $key = openssl_pkey_get_private('file://'.$keyfile);

  $header = ['alg'=>'ES256','kid'=>$keyid];
  $claims = ['iss'=>$teamid,'iat'=>time()];

  $header_encoded = base64($header);
  $claims_encoded = base64($claims);

  $signature = '';
  openssl_sign($header_encoded . '.' . $claims_encoded, $signature, $key, 'sha256');
  $jwt = $header_encoded . '.' . $claims_encoded . '.' . base64_encode($signature);

  // only needed for PHP prior to 5.5.24
  if (!defined('CURL_HTTP_VERSION_2_0')) {
      define('CURL_HTTP_VERSION_2_0', 3);
  }

  $http2ch = curl_init();
  curl_setopt_array($http2ch, array(
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
    CURLOPT_URL => "$url/3/device/$token",
    CURLOPT_PORT => 443,
    CURLOPT_HTTPHEADER => array(
      "apns-topic: {$bundleid}",
      "authorization: bearer $jwt"
    ),
    CURLOPT_POST => TRUE,
    CURLOPT_POSTFIELDS => $message,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HEADER => 1
  ));

  $result = curl_exec($http2ch);
  if ($result === FALSE) {
    throw new Exception("Curl failed: ".curl_error($http2ch));
  }

  $status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
  echo $status;

  function base64($data) {
    return rtrim(strtr(base64_encode(json_encode($data)), '+/', '-_'), '=');
  }

?>
Falito answered 14/8, 2017 at 14:12 Comment(9)
I'm getting an error as 'Unexpected HTTP/1.x request: POST /3/device/5cba9501b6b6b3d6xxxxxxxxxxxxx'. Can you suggest a solution?Gopher
Can you try to restart the webserver as suggested in this answer: https://mcmap.net/q/829296/-unexpected-http-1-x-request-post-3-device-xxxx ?Falito
I was getting this error when i tried to run the above code ' Curl failed: No URL set!' even though am passing the url. so i just replaced the curl_setopt_array to curl_setopt and it worked for me.Lammas
@Gopher I managed to solve this issue, see here: https://mcmap.net/q/829296/-unexpected-http-1-x-request-post-3-device-xxxxSupposition
@RoelKoops Could you tell me how we can generate apple developer token for musickit apisMcauliffe
@RoelKoops what should we pass in $signature parameter?Present
@JaySojitra: You don't have to fill $signature yourself. This will be done by openssl_sign when the call is succesfull, see php.net/manual/en/function.openssl-sign.phpFalito
I only have access to curl version 7.29.0. Is there any way to run this with this version?Speculation
@Chris: I don't think so, curl 7.29.0 is missing HTTP/2 supportFalito
H
2

I also struggled to find a simple library to send APNS notifications with a .p8 file in PHP. I found the edamov/pushok library to be the most straightforward and object-oriented. Just install the package with composer require edamov/pushok and follow the instructions in Getting Started.

Hawaiian answered 28/10, 2019 at 17:46 Comment(0)
D
1

I have been trying to send push notification with new JWT based push notification service using PHP. Its was definitely not a easy task.

I have uploaded project on GitHub. You can download from there and make sure you replace your .p8 file with existing .p8 file.

Then in push.php file you need to replace your kid, iss(Team ID), token and app_bundle_id.

Go to the directory and from terminal run the command php push.php. If everything goes well then you should receive push notification.

This solution works well for me. Just make sure that you don't get any errors in terminal.

I hope this helps.

Dowel answered 13/1, 2017 at 19:59 Comment(2)
I have try but not work in php5.6 version give error.Huan
@Dowel can you explain how can i use it n laravelGarnishee

© 2022 - 2024 — McMap. All rights reserved.