如何在Python中验证StoreKit 2交易jwsRepresentation及App Store V2通知signedPayload?
服务器端验证StoreKit 2的jwsRepresentation与App Store Notifications V2的signedPayload
其实这两个格式都是标准的JWT(JSON Web Token),遵循JWS(JSON Web Signature)规范,苹果官方文档虽然没明确写服务器端验证步骤,但按照通用JWT验证流程结合Apple的规则来处理就可以,具体步骤如下:
1. 获取Apple的签名公钥
不管是StoreKit 2的交易凭证还是V2通知的签名 payload,都是用Apple的官方公钥签名的。你可以从苹果的官方端点获取对应公钥集合:
- 对于StoreKit 2交易:从苹果官方的Apple ID认证公钥端点获取
- 对于App Store Notifications V2:从App Store StoreKit官方公钥端点获取
获取到的公钥是JWKS格式,包含多个带kid(密钥ID)的公钥,你需要把这些公钥缓存起来,不用每次验证都请求——苹果不会频繁轮换公钥,缓存24小时完全没问题。
2. 解析JWT结构,匹配对应公钥
把拿到的jwsRepresentation或signedPayload按.分割成三部分:Header、Payload、Signature。先解码Header部分(Base64URL解码),拿到里面的kid字段,用这个kid在你缓存的公钥集合里找到对应的公钥。
3. 验证JWT签名
用匹配到的公钥,结合JWT的算法(一般是ES256椭圆曲线算法),验证Signature的有效性。这里强烈建议用成熟的JWT验证库,比如:
- Python:
PyJWT - Node.js:
jsonwebtoken - Java:
JJWT
不要自己实现签名验证逻辑,容易踩坑。
4. 验证Payload中的关键字段
签名过了不代表内容完全可信,还要验证几个核心字段:
- 受众(
aud):必须和你的App Bundle ID完全一致,防止别人用其他App的凭证攻击你的服务器 - 颁发者(
iss):- StoreKit 2交易的
iss必须是https://appleid.apple.com - App Store Notifications V2的
iss必须是https://apps.apple.com
- StoreKit 2交易的
- 过期时间(
exp):确保当前时间在exp之前,拒绝过期的凭证 - 业务相关字段:比如交易ID(
transactionId)、通知类型(notificationType)等,要和你系统中的记录或预期逻辑匹配,防止重复处理或无效通知
5. 处理验证结果
如果所有验证步骤都通过,就可以信任Payload里的内容,执行后续业务操作(比如更新用户订阅状态、记录交易流水等);只要有一步验证失败,直接拒绝这个请求,不要进行任何业务处理。
额外注意事项
- 不要硬编码公钥,一定要动态获取,苹果可能会轮换密钥
- 公钥缓存要设置合理的过期时间,过期后重新拉取
- 处理公钥更新的情况:如果验证时找不到对应
kid的公钥,立即重新拉取最新的公钥集合再尝试验证一次
内容的提问来源于stack exchange,提问作者Taylor Hughes
相关产品推荐
相关产品推荐

