Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send iOS Push notification in php with .p8 file

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?

like image 384
Cam Connor Avatar asked Jan 13 '17 06:01

Cam Connor


People also ask

What is .p8 file in iOS?

. p8 Apple Push Notifications service (APNs) is created in the Apple developer account “keys” section. it is useful for handling the push notification for All bundle Id that is registered in developer account & there is no issue of expiry.

What is p8 and P12 file?

p8 files are keys used to create tokens, and those . p12 files are used as certificates? authentication. apple-push-notifications.

Can PWA send push notifications iOS?

Progressive Web Apps is a trend in 2019 and web push notifications for iOS are not supported right now.


1 Answers

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)), '+/', '-_'), '=');
  }

?>
like image 65
Roel Koops Avatar answered Sep 19 '22 16:09

Roel Koops