如何像验证Google IdToken一样校验Apple IdToken?
核心结论
Apple 提供官方IdToken校验能力,没有推出和Google完全等价的全平台一键校验SDK,但给出了明确的官方校验规范,且各端系统框架内置了对应校验逻辑。两者IdToken的核心验证逻辑都是基于OIDC标准的JWT校验,但具体规则存在明确差异。
和Google IdToken校验的核心差异
- 公钥处理逻辑:Google官方SDK会自动拉取、定期轮换平台公钥,开发者不需要关心公钥缓存逻辑;Apple虽然也会定期轮换公钥,但明确要求开发者校验时必须匹配JWT头里的
kid字段选择对应公钥,且公钥缓存时长不能超过公钥接口返回的max-age值,禁止硬编码固定公钥。 - 强制校验项不同:Google的nonce校验属于可选配置,开发者可以按需开启;Apple要求必须校验请求时传入的自定义nonce和token里携带的nonce值完全一致,否则无法防御重放攻击。
- 受众(aud)校验规则不同:Google只需要校验aud字段和申请的OAuth客户端ID匹配即可;Apple的IdToken按签发场景区分aud值,iOS原生应用签发的token对应aud是应用Bundle ID,Web/服务端场景签发的token对应aud是开发者配置的Service ID,跨场景混用aud会直接校验失败。
- 签名算法限制:Google支持RS256、ES256等多种签名算法,Apple目前仅使用RS256算法签发IdToken,校验时如果发现alg字段不是RS256可直接判定为无效token。
官方标准校验操作方法
- 原生Apple端(iOS/macOS/watchOS/tvOS):直接使用系统自带的
AuthenticationServices框架拉起Apple登录,用户授权成功后返回的ASAuthorizationAppleIDCredential实例中,identityToken字段对应的就是已经过系统本地校验的有效IdToken,开发者不需要额外做签名验证,直接把token字符串传给服务端即可。 - 服务端/Web端校验:按照以下步骤操作即可,不需要依赖专门的Apple官方SDK:
- 先解析待校验IdToken的头部信息,拿到
alg和kid字段,如果alg不是RS256直接判定无效。 - 拉取Apple公开的签名公钥集合,用第一步拿到的kid匹配对应公钥,注意公钥缓存时长严格按照接口返回的Cache-Control头里的max-age设置,不要永久缓存。
- 用匹配到的公钥校验JWT的签名完整性,签名不通过直接判定无效。
- 校验payload固定字段合法性:
iss字段必须严格等于https://appleid.apple.comaud字段必须和当前场景下的客户端标识完全匹配exp字段的UTC时间戳必须晚于当前时间,iat字段的签发时间和当前时间差建议控制在10分钟以内,避免旧token被重放- 如果拉起登录时传入了自定义nonce,必须校验token内的nonce值和本地存储的请求生成值完全一致
- 校验通过后,可直接从payload中读取
sub(Apple侧用户唯一固定标识)、email(用户邮箱,用户选择隐藏真实邮箱时会返回Apple私域转发邮箱)、email_verified(邮箱是否完成验证)、is_private_email(是否为Apple转发私域邮箱)字段使用,不需要额外调用接口换取用户信息。
- 先解析待校验IdToken的头部信息,拿到
实际开发中不需要手写JWT签名校验逻辑,主流开源JWT库(Java端JJWT、Python端PyJWT、Node.js端jsonwebtoken、Go端jwt-go等)都可以按照上述规则快速实现校验,整体开发成本和接入Google校验SDK相差不大。
内容的提问来源于stack exchange,提问作者Zephyr
相关产品推荐
相关产品推荐

