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

Apple Watch 配套应用中访问令牌与刷新令牌的处理

解决Apple Watch刷新令牌不影响iPhone应用令牌的问题

问题根源

你的问题核心在于OAuth2协议的刷新令牌机制:大多数认证服务在刷新令牌时,会废弃旧的刷新令牌并返回新令牌。当iPhone和Watch共用同一个刷新令牌时,Watch端调用刷新接口后,服务器会失效旧令牌,导致iPhone端存储的刷新令牌无法再使用,进而触发登出。

解决方案

1. 为Watch分配独立的刷新令牌

这是最彻底的解决方案,需要服务器端配合支持多设备令牌管理:

  • iPhone登录成功后,除了自身的访问/刷新令牌,发起一个"Watch设备绑定"请求,服务器为该Watch生成独立的刷新令牌(与iPhone的刷新令牌相互独立);
  • 通过WatchConnectivity将初始访问令牌+绑定凭证(如临时授权码)发送给Watch,Watch使用绑定凭证向服务器请求专属的刷新令牌,并存入本地钥匙串;
  • 后续Watch刷新令牌时,仅使用自己的独立刷新令牌,不会影响iPhone端的令牌有效性。

2. 优化跨设备令牌同步逻辑

如果暂时无法修改服务器端,可通过调整客户端同步策略避免互相影响:

  • 两端仅同步访问令牌,不同步刷新令牌;
  • iPhone端刷新令牌后,将新的访问令牌通过WatchConnectivity同步给Watch,覆盖Watch的访问令牌,但保留Watch的刷新令牌;
  • Watch端刷新令牌后,同样仅同步新的访问令牌给iPhone,不修改iPhone的刷新令牌;
  • 这种方式下,两端各自用自己的刷新令牌刷新,仅共享最新的访问令牌,避免互相踢下线。

3. 服务器端调整令牌策略(可选)

如果服务器可控,可做以下优化:

  • 启用刷新令牌滚动有效期:刷新时返回新的刷新令牌,同时保留旧的刷新令牌一段时间(如5-10分钟),给两端足够的同步窗口;
  • 支持多设备刷新令牌关联:将同一个用户的多个设备刷新令牌关联到用户ID下,刷新某一个设备的令牌时,仅失效该设备的旧令牌,不影响其他设备。

代码示例(Swift)

Watch端刷新令牌并同步访问令牌

func refreshWatchTokens() {
    guard let refreshToken = KeychainService.load(key: "watch_refresh_token") else { return }
    
    // 调用服务器刷新接口,获取新的访问令牌和Watch专属的刷新令牌
    AuthAPI.refreshToken(refreshToken: refreshToken) { [weak self] result in
        guard let self = self else { return }
        switch result {
        case .success(let newTokens):
            // 保存Watch自己的令牌
            KeychainService.save(key: "watch_access_token", value: newTokens.accessToken)
            KeychainService.save(key: "watch_refresh_token", value: newTokens.refreshToken)
            
            // 仅同步访问令牌到iPhone
            if WCSession.default.isReachable {
                do {
                    try WCSession.default.updateApplicationContext([
                        "shared_access_token": newTokens.accessToken
                    ])
                } catch {
                    print("Sync access token to iPhone failed: \(error.localizedDescription)")
                }
            }
        case .failure(let error):
            print("Refresh watch tokens failed: \(error.localizedDescription)")
        }
    }
}

iPhone端接收同步的访问令牌

// 实现WCSessionDelegate方法
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
    if let newAccessToken = applicationContext["shared_access_token"] as? String {
        // 更新iPhone的访问令牌,保留原有刷新令牌
        KeychainService.save(key: "iphone_access_token", value: newAccessToken)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:55:16