转载自:https://zhuanlan.zhihu.com/p/622475157
做App总少不了消息推送,公司的App为了开发敏捷方便都直接上的三方推送诸如某盟、某推、某光,安卓和苹果都一套代码,高效好维护,只要按时给推送vip付费就好了。最近心血来潮想手搓下苹果的消息推送,踩踩以前没踩过的坑。
看了下苹果官方文档感觉并不困难,文档详情戳这里
Sending Notification Requests to APNs | Apple Developer Documentation
恰逢chatGPT大火赶下时髦,直接问了ai代码怎么写
charGPT3.5的回答ai回答得有模有样,我里面换上证书和相关参数尝试,然后发现死活不行,苹果那边没反应。
一查文档发现其实苹果这边服务器推送大致分了两种模式:
一种是基于ssl证书模式推送,另一种是根据p8证书生产jwt token授权来推送。
显然代码给的是第一种,然后看了苹果的官方文档2021年就已经废弃了第一种模式并且强行要求使用http2请求,看来chatGPT3.5的投喂数据截止于2021年所言非虚。
苹果官方强行要求http2这里我踩了两个大坑:
第一个是苹果证书ssl模式下要pem证书,我拿到的是p12证书,只能先用OpenSSL转成pem公钥和私钥,后来发现要公钥和私钥放在一起合成一个pem第一张图的代码才能用。然后转为jwt授权模式后要的是p8证书,之前的pem证书生成的token死活过不了。
第二个是我这边的服务器环境curl并不支持http2,一直报错Unexpected HTTP/1.x request: POST /3/device/XXXX。后来我只好重新编译curl和php相关的扩展直接升级到了curl 8.1.0。参考连接
下面是推送和jwt生成demo
<?php //jwt token模式下的苹果推送 $device_token = 'your_device_token'; //苹果给的设备推送token $message = 'Hello, world!'; //要推送的消息 // Create the notification payload $payload = array( 'aps' => array( 'alert' => $message, 'sound' => 'default' ) ); $payload_json = json_encode($payload); //正式环境推送地址 $url = 'https://api.push.apple.com:443/3/device/' . $device_token; //沙盒推送地址 //$url = "https://api.sandbox.push.apple.com:443/3/device/".$device_token; $headers = array( 'Authorization: Bearer 你生成的jwt_token', 'Content-Type: application/json' ); $ch = curl_init($url); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload_json); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); //这里很关键,以http2发送请求,如果你的curl不支持http2则需要看前面的步骤 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // Check the response if ($http_code == 200) { echo 'Notification sent successfully.'; } else { echo 'Notification failed with error code: ' . $http_code; }
生成 jwt_token
<?php //jwt token生成代码 $key_id = 'your_key_id'; $team_id = 'your_team_id'; $pkey_file = 'AuthKey_your_key_id.p8'; //p8证书文件,我在这里填的绝对地址 // token过期时间 $expires = time() + 3600; // Generate the JWT header $header = array( 'alg' => 'ES256', 'kid' => $key_id ); $jwt_header = base64_encode(json_encode($header)); // Generate the JWT payload $payload = array( 'iss' => $team_id, 'iat' => time(), 'exp' => $expires, 'aud' => 'https://appleid.apple.com', 'sub' => 'your_bundle_id' //这里填你的App包名 ); $jwt_payload = base64_encode(json_encode($payload)); //载入证书文件 $pkey_contents = file_get_contents($pkey_file); $pkey = openssl_get_privatekey($pkey_contents); //JWT 签名 $signature = ''; openssl_sign($jwt_header . '.' . $jwt_payload, $signature, $pkey, 'sha256'); $jwt_signature = base64_encode($signature); // Generate the final JWT $jwt = $jwt_header . '.' . $jwt_payload . '.' . $jwt_signature; // Print the JWT echo $jwt;
标签:ch,jwt,APNs,苹果,http2,curl,推送,payload From: https://www.cnblogs.com/zinging/p/17792407.html