Python(Django)向Chrome推送Web Notification时触发400错误
看起来你碰到了Web Push里的常见差异问题——Firefox能正常接收推送,Chrome却返回400 UnauthorizedRegistration,我之前处理过类似情况,核心是Chrome对VAPID密钥和请求格式的要求比Firefox更严格,给你梳理几个能快速排查解决的方向:
1. 补全VAPID配置里的必填字段
Chrome强制要求VAPID的sub声明(Firefox不强制),这个字段必须是邮箱格式的联系信息,用来让推送服务方联系你。如果你的代码里没加这个,大概率是报错原因:
from pywebpush import webpush, WebPushException import json def send_push(subscription, payload): # 读取PEM格式的私钥(后面会说怎么转) vapid_private_key = open("path/to/your/private_key.pem", "r").read() vapid_claims = { "sub": "mailto:your-email@example.com" # 必须是这个格式! } try: webpush( subscription_info=subscription, data=json.dumps(payload), vapid_private_key=vapid_private_key, vapid_claims=vapid_claims ) except WebPushException as e: print(f"Push failed: {e}")
2. 确保私钥是PEM格式
你从web-push-codelab拿到的私钥是base64字符串,pywebpush在Chrome环境下需要PEM格式的密钥。可以用openssl转一下:
# 把你的base64私钥转成二进制文件 echo "你的base64私钥字符串" | base64 -d > private_key.bin # 再转成PEM格式 openssl ec -in private_key.bin -inform DER -out private_key.pem -outform PEM
之后代码里读取这个PEM文件就行,不要直接用原始的base64字符串。
3. 检查订阅信息的完整性
Chrome对订阅对象的格式要求更严,确保你存储的subscription是前端返回的完整对象:
- 必须包含
endpoint、keys.p256dh、keys.auth三个字段,不能遗漏或在存储/传递过程中被篡改(比如重复编码base64)。 - 可以尝试在Chrome上重新订阅一次,用新的订阅对象测试推送,排除旧订阅失效的可能。
4. 验证推送数据格式
确保你传给webpush的data是JSON字符串(用json.dumps()转换),而不是原始字典。Chrome对数据格式的校验比Firefox更严格,格式不对也可能触发这个错误。
按这几个步骤排查下来,基本能解决Chrome的UnauthorizedRegistration问题,我当时就是因为漏加了sub字段踩的坑,补完之后就正常了。
内容的提问来源于stack exchange,提问作者Avinash Gupta
相关产品推荐
相关产品推荐

