使用 PHP 脚本通过 APNs 发送推送消息

HTTP/2 是新标准(从 2020 年 11 月起,是连接 APNS 的唯一方式)在本文中,我将解释如何使用 PHP 使用 JWT 令牌(推荐)或使用证书连接 APNS。

Apple 向 iPhone、iPad 甚至 Apple 手表发送推送通知的服务称为 APNS:Apple Push Notification Service)。

为了发送推送通知,您需要一个 IOS 应用程序和一个服务器来发送消息。在本文中,我将提供有关如何使用库通过 PHP 发送消息的信息,以便更轻松地生成所需的 JWT 令牌。

您需要什么才能通过 APNS 发送推送通知?

远程通知的传递涉及几个关键组件。我们将需要一个接收器(iPad、iPhone 等)和一个服务器来从(提供者服务器)发送消息

  • 您公司/个人的服务器(称为提供商服务器)——我们将在我们的提供商服务器上使用 PHP

  • Apple 推送通知服务 (APN) -- 来自 Apple(.p8 文件)的私钥(或证书)

  • 用户(苹果)设备(iPad、iPhone等)

  • IOS 应用程序(您的应用程序在用户设备上运行)- 例如:nl.samauto.ios-application

从苹果获取私钥

Apple 推送通知服务 (APN) 必须知道用户设备的地址,然后才能向该设备发送通知。该地址采用对设备和您的应用程序 (nl.samauto.ios-application) 唯一的设备令牌的形式。在启动时,您的应用程序与 APN 通信并接收其设备令牌,然后您将其转发到您的提供商服务器(我们将使用 PHP 构建的服务器)。我们的服务器将在发送给 Apple 的任何通知中包含该令牌。

前往Developer.apple.com并使用您的 AppleId 登录。

转到“证书、标识符和配置文件 > 密钥”

为您的应用程序生成一个新密钥,确保启用推送通知功能。

下载 .p8 文件并将其保存到安全位置。

无法再次下载(苹果删除私钥)

让我们构建 PHP 服务器!

我们将使用 PHP 构建我们的服务器。

为了向 APNS 进行身份验证,我们使用 JWT(JSON Web Tokens – RFC 7519)来创建与 Apple 服务器的基于令牌的身份验证连接。

我们将使用 composer 添加一个由 Luís Cobucci 开发的包 (jwt)。lcobucci/jwt 在 GitHub 上或在 packagist.org

要将包(通过 composer)添加到项目中,请使用以下命令:

composer require lcobucci/jwt

我们可以使用以下脚本:

<?php

use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Ecdsa\Sha256;
use Lcobucci\JWT\Configuration;

$config = $container->get(Configuration::class);
assert($config instanceof Configuration);

$device_token = "device_token_here";
$apns_topic = 'to.dev.ios-application';
$p8file = "/home/dave/samauto/key_from_apple.p8";

$token = (string) $config->createBuilder()
->issuedBy("DEF123GHIJ") // (iss claim) // teamId
->issuedAt(time()) // time the token was issuedAt
->withHeader('kid', "ABC123DEFG")
->setKey('file://' . $p8file)
->setSigner(new Sha256()) // APNs only supports the ES256 algorithm
->getToken(); // get the generated token

$payloadArray['aps'] = [
  'alert' => [
    'title' => "Dev.To Push Notification", // title of the notification
    'body' => "Visit SamAuto.nl for more awesome scripts", // content/body of the notification
  ],
  'sound' => 'default',
  'badge' => 1
];

$payloadJSON = json_encode($payloadArray);

$url = "https://api.sandbox.push.apple.com/3/device/$device_token";
$ch = curl_init($url);

curl_setopt($ch, CURLOPT_POSTFIELDS, $payloadJSON);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $token","apns-topic: $apns_topic"]);
$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);

我将逐步解释脚本。

首先,我们需要来自 IOS 设备的 deviceId、安装在 IOS 设备上的应用程序标识符以及 .p8 文件的文件路径。

// replace the device token with "device_token_here"
$device_token = "device_token_here";

// use your IOS application ID
$apns_topic = 'to.dev.ios-application';

// replace $p8file with the location to your .p8 file you downloaded from Apple.
$p8file = "/home/dave/samauto/key_from_apple.p8";

接下来,我们将使用 JWT 库生成 JWT 令牌来验证对 Apple API 的 HTTP/2 调用。

// Replace "DEF123GHIJ" with your TeamId
// Replace "ABC123DEFG" with your (Encryption) KeyId

$token = (string) $config->createBuilder()
->issuedBy("DEF123GHIJ") // (iss claim) // teamId
->issuedAt(time()) // time the token was issuedAt
->withHeader('kid', "ABC123DEFG")
->setKey('file://' . $p8file)
->setSigner(new Sha256()) // APNs only supports the ES256 algorithm
->getToken(); // get the generated token

// $token will now contain a JWT Token for example:
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

您可以在JWT.IO上找到有关 JWT 令牌的更多信息

脚本的下一部分是创建一个有效负载以发送到苹果并编码为 JSON。

$payloadArray['aps'] = [
  'alert' => [
    'title' => "Dev.To Push Notification", // title of the notification
    'body' => "Visit SamAuto.nl for more awesome scripts", // content/body of the notification
  ],
  'sound' => 'default',
  'badge' => 1
];

$payloadJSON = json_encode($payloadArray);

有效载荷将如下所示:

{
    "aps": {
        "alert": {
            "title": "Dev.To Push Notification",
            "body": "Visit SamAuto.nl for more awesome scripts"
        },
        "sound": "default",
        "badge": 1
    }
}

我们会将其发送到 Apple 的沙盒 URL (https://api.sandbox.push.apple.com/)

并附加 "3/device/" 和 $device_token 的值

接下来我们将构建一个 cURL 请求(确保您安装了启用 HTTP/2 的 CURL 版本)

curl_setopt($ch, CURLOPT_POSTFIELDS, $payloadJSON);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $token","apns-topic: $apns_topic"]);
$response = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

如果一切顺利,您应该会看到 200 OK HTTP 状态代码。

快乐黑客!

Logo

ModelScope旨在打造下一代开源的模型即服务共享平台,为泛AI开发者提供灵活、易用、低成本的一站式模型服务产品,让模型应用更简单!

更多推荐