在拿到App发送过来的deviceToken和产品经理的推送payload之后,作为服务端程序员的我们,还需要做一个操作,那就是生成并加密JSON Web Token (JWT),然后才能把这三个一起发送给APNs。
关于JWT身份验证令牌的概念以及如何在苹果开发者网站获取签名密钥(Key)在我的教程中都有讲解,不熟悉的同学可以再去看一下。
这里主要说一下如何在服务端用PHP语言
1.生成并加密JWT
2.向APNs发送推送请求
使用框架:jwt-framework
1.生成并加密JWT
用composer安装这个框架包:
composer require web-token/jwt-framework
在文件中引入:
<?php
require_once 'vendor/autoload.php';
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\KeyManagement\JWKFactory;
use Jose\Component\Signature\JWSBuilder;
use Jose\Component\Signature\Algorithm\ES256;
use Jose\Component\Signature\Serializer\CompactSerializer;
创建JWT:
<?php
function getToken($cerPath, $keyID, $teamId) {
// 1.创建ES256算法
$algorithmManager = AlgorithmManager::create([
new ES256()
]);
// 2.用苹果开发者网站创建的p8文件(签名密钥)创建JSON web key($cerPath为p8文件的路径)
$jwk = JWKFactory::createFromKeyFile($cerPath);
// JSON转化器
$jsonConverter = new StandardConverter();
// 实例化JWSBuilder
$jwsBuilder = new JWSBuilder(
$jsonConverter,
$algorithmManager
);
// 3.创建JWT的payload部分(iat为当前时间戳,iss为开发者账号TeamID)
$payload = $jsonConverter->encode([
'iat' => time(),
'iss' => $teamId,
]);
// 4.生成并加密JWT
$jws = $jwsBuilder
->create() // 创建
->withPayload($payload) // 设定JWT的payload
->addSignature($jwk, ['alg' => 'ES256', 'kid' => $keyID]) // 用JSON web key和苹果规定的JWTheader签名加密
->build(); // 生成
$serializer = new CompactSerializer($jsonConverter); // 序列化工具
// 5.序列化JWT
$token = $serializer->serialize($jws); // 序列化上面的jws,只有一个签名,故index为0的即可
return $token;
}
2.向APNs发送推送请求
<?php
function sendPush($deviceToken, $authToken, $payload) {
// 1.创建一个带有deviceToken的path(其实就是字串)-苹果规定必须这么写
$path = '/3/device/'.$deviceToken;
$curl = curl_init();
curl_setopt_array($curl, array(
// 2.带上deviceToken向APNs服务器请求
CURLOPT_URL => "https://api.development.push.apple.com:443".$path,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_TIMEOUT => 30,
CURLOPT_CUSTOMREQUEST => "POST",
// 3.把推送的payload放入请求体+设置请求头
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"apns-expiration: 0",
"apns-push-type: alert",
"apns-topic: com.example.app", // 4.我们App的bundleID
"authorization: bearer ".$authToken // 5.上面生成并加密的JWT
),
));
//发送请求
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
}
调用上述两个函数并传参:
<?php
$token = getToken('key/path/mykey.p8', 'Key ID', 'Team ID');
$payload = json_encode(['aps' => ['alert' => 'Hi there!']]);
sendPush('9fbb61136e03c.................', $token, $payload);