You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向APNs发送Web Push返回403 Forbidden问题求助

Web Push在iPhone/Safari PWA中返回403 Forbidden问题求助

我的Java服务器向Android/Chrome端的PWA发送Web Push可正常运行,但向iPhone/Safari端的PWA发送时返回403 Forbidden错误,特此求助。

Android端正常流程

  • 通过Chrome在Android手机上安装PWA
  • 用户点击应用内的订阅按钮并授予权限
  • 应用通过服务器的VAPID公钥获取Subscription
  • PWA将Subscription(endpoint、密钥)发送至服务器
  • 服务器向订阅端点(https://fcm.googleapis.com/fcm/send/...)发送Web Push
  • FCM返回201 Created响应
  • PWA的Service Worker接收到"push"事件并展示通知

向fcm.googleapis.com发送的请求

url:https://fcm.googleapis.com/wp/evZRV...IeBQGGaRfGK
Authorization=vapid t=eyJ0eXAiOi...o2jHfWJGw, k=BHBlZKwyYa...SclQckMDxE
Content-Encoding=aes128gcm
TTL=2419200
Crypto-Key=p256ecds...lQckMDxE=
Content-Type=application/octet-stream
method:POST
protocol version:HTTP/1.1
entity:[Content-Length: 219,Chunked: false]

响应信息

statusline:HTTP/1.1 201 Created
Location=https://fcm.googleapis.com/0:1705097911549557%0f493ae6f9fd7ecd
X-Content-Type-Options=nosniff
X-Frame-Options=SAMEORIGIN
X-Xss-Protection=0
Date=Fri, 12 Jan 2024 22:18:31 GMT
Content-Length=0
Content-Type=text/html; charset=UTF-8
Alt-Svc=h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
protocol version:HTTP/1.1
entity:[Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]

iPhone端失败流程

  • 通过Safari在iPhone上安装PWA
  • 用户点击应用内的订阅按钮并授予权限
  • 应用通过服务器的VAPID公钥获取Subscription
  • PWA将Subscription(endpoint、密钥)发送至服务器
  • 服务器向订阅端点(https://web.push.apple.com/...)发送Web Push
  • 收到403 Forbidden响应
  • PWA的Service Worker从未接收到"push"事件

向web.push.apple.com发送的请求

url:https://web.push.apple.com/QPU8aHza...q44-RonI
Authorization=vapid t=eyJ0eXAiO...DKVX7h5g, k=BHBlZKwy...QckMDxE
Content-Encoding=aes128gcm
TTL=2419200
Crypto-Key=p256ecdsa=BHBlZKwy...clQckMDxE=
Content-Type=application/octet-stream
method:POST
protocol version:HTTP/1.1
entity:[Content-Length: 219,Chunked: false]

响应信息

statusline:HTTP/1.1 403 Forbidden
content-type=text/plain; charset=UTF-8
apns-id=3597065D-3C81-ED1D-A56C-E5CED97D3BC1
protocol version:HTTP/1.1
entity:org.apache.http.client.entity.DecompressingEntity@6cbc2aee

使用的代码

我使用webpush-java库准备Web Push请求,发送代码如下:

JSONObject json = new JSONObject();
json.put("title", "Hello");
json.put("body", "This is a test.");
json.put("sub","mailto:myemail@mycompany.com");

PushService pushService = new PushService(publicKey, privateKey);
Notification notification = new Notification(subscription, json);
HttpPost httppost = pushService.preparePost(notification, Encoding.AES128GCM);
HttpClient httpclient = HttpClients.createDefault();
HttpResponse response = httpclient.execute(httppost);

解决建议

1. 修正VAPID的sub声明位置

你当前将sub字段放在了推送payload中,但Apple要求该字段必须包含在VAPID的JWT payload里,而非推送内容中。修改代码,在创建PushService时指定联系人邮箱:

PushService pushService = new PushService(publicKey, privateKey, "mailto:myemail@mycompany.com");

或者在构建Notification时设置:

Notification notification = new Notification(subscription, json)
    .withContact("mailto:myemail@mycompany.com");

这样库会自动将sub加入VAPID JWT的claims,符合Apple的验证要求。

2. 验证VAPID密钥合规性

确保你的VAPID密钥对是基于P-256椭圆曲线生成的(Apple仅支持该曲线),密钥无额外空格或格式错误。若不确定,可重新生成密钥对测试。

3. 检查请求头格式

确认Crypto-Key头中的p256ecdsa参数值与Authorization头里的k参数完全一致,无编码错误。webpush-java库通常会正确处理,但可手动核对生成的请求头。

4. 确认payload大小

Apple对加密后的Web Push payload限制为4096字节,当前测试内容虽小,但后续推送需确保不超过该限制。

5. 排查服务器IP问题

若服务器曾发送大量无效请求,可能被Apple屏蔽。可尝试更换服务器IP,或检查Apple推送服务状态。

内容的提问来源于stack exchange,提问作者ScottD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 12:22:40