SwiftUI应用中撤销Apple登录令牌后,如何获取新授权码及刷新令牌?
Sign in with Apple 撤销令牌后重新登录无法获取新授权码的解决方案
问题根源
你遇到的核心问题是:用户删除账号后重新登录时,客户端未触发全新授权流程,Apple返回缓存的旧授权信息(含已过期的授权码),导致服务器无法获取新令牌。
解决步骤
1. 强制触发重新授权请求
创建ASAuthorizationAppleIDRequest时,必须设置prompt属性为.login或.consent,强制Apple弹出登录界面生成新授权码,而非返回缓存数据。
示例代码:
func startAppleSignIn() { let provider = ASAuthorizationAppleIDProvider() let request = provider.createRequest() request.requestedScopes = [.fullName, .email] // 强制用户重新登录,生成新授权码 request.prompt = .login let controller = ASAuthorizationController(authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self controller.performRequests() }
.login:强制用户重新输入Apple ID密码,确保本人操作,必生成新授权码。.consent:适用于需重新获取用户同意的场景(如权限变更),同样生成新授权码。
2. 清理本地Apple登录状态
用户删除账号后,彻底清除应用本地存储的Apple登录相关数据:
- 删除保存的
userIdentifier(Apple返回的唯一用户ID) - 删除本地缓存的授权码、令牌信息
- 若使用Keychain存储凭证,同步删除该条目
确保下次登录时,ASAuthorizationAppleIDProvider判定为新用户请求,不复用旧授权缓存。
3. 服务器端配合处理
- 调用Apple撤销API后,确认令牌已成功撤销(HTTP 200状态码表示成功)。
- 若服务器收到授权码后返回
invalid_grant错误(授权码过期或已使用),需明确返回错误给客户端,触发客户端重新发起授权请求。
4. 遵守授权码使用规则
Apple授权码的核心特性:
- 仅能使用一次,使用后立即失效。
- 有效期约5分钟,必须在有效期内完成令牌交换。
服务器绝不能缓存授权码,每次收到新授权码都要立即向Apple服务器交换令牌。
额外提示
若用户在系统设置中撤销应用的Sign in with Apple权限,客户端可通过ASAuthorizationAppleIDProvider().getCredentialState(forUserID: userIdentifier)检测到状态变更(返回.revoked),此时应自动清理本地状态,引导用户重新登录。
内容的提问来源于stack exchange,提问作者guycas
相关产品推荐
相关产品推荐

